diff --git a/src/FuzeWorks/Forms/Field.php b/src/FuzeWorks/Forms/Field.php index b895c44..c627447 100755 --- a/src/FuzeWorks/Forms/Field.php +++ b/src/FuzeWorks/Forms/Field.php @@ -44,7 +44,7 @@ abstract class Field protected ?string $label = null; protected ?string $note = null; protected mixed $value = null; - protected array $errors; + protected array $errors = []; protected bool $lock = false; protected bool $optional = false; protected bool $validated = false; diff --git a/test/base/FieldTest.php b/test/base/FieldTest.php new file mode 100644 index 0000000..044364e --- /dev/null +++ b/test/base/FieldTest.php @@ -0,0 +1,386 @@ +getMockForAbstractClass(Field::class, ['testName']); + $this->assertEquals('testName', $stub->getName()); + $this->assertInstanceOf(Field::class, $stub); + } + + /** + * @depends testFoundation + */ + public function testName() + { + // Set the name originally + $stub = $this->getMockForAbstractClass(Field::class, ['originalName']); + $this->assertEquals('originalName', $stub->getName()); + } + + /** + * @depends testFoundation + */ + public function testLabel() + { + // Set the label originally + $stub = $this->getMockForAbstractClass(Field::class, ['originalName']); + + // First test the label if none is set + $this->assertEquals('OriginalName', $stub->getLabel()); + + // Set the label + $stub->setLabel('newLabel'); + $this->assertEquals('newLabel', $stub->getLabel()); + } + + /** + * @depends testFoundation + */ + public function testIdentifier() + { + // Set the label originally + $stub = $this->getMockForAbstractClass(Field::class, ['originalName']); + + // This test presumes that the field always has a formName + $stub->setFormName('testForm'); + + // First test the label if none is set + $this->assertEquals('testForm_originalName', $stub->getId()); + + // Set the label + $stub->setId('newIdentifier'); + + // Test if the identifier is set + $this->assertEquals('testForm_newIdentifier', $stub->getId()); + } + + /** + * @depends testFoundation + */ + public function testNote() + { + // Set the label originally + $stub = $this->getMockForAbstractClass(Field::class, ['originalName']); + + // First test the label if none is set + $this->assertNull($stub->getNote()); + + // Set the label + $stub->setNote('newNote'); + $this->assertEquals('newNote', $stub->getNote()); + } + + /** + * @depends testFoundation + */ + public function testValue() + { + // Set the label originally + $stub = $this->getMockForAbstractClass(Field::class, ['originalName']); + + // First test the label if none is set + $this->assertNull($stub->getValue()); + + // Set the label + $stub->setValue('newValue'); + $this->assertEquals('newValue', $stub->getValue()); + } + + /** + * @depends testValue + */ + public function testLock() + { + // Create the field + $stub = $this->getMockForAbstractClass(Field::class, ['originalName']); + + // Set the value + $stub->setValue('newValue'); + $this->assertEquals('newValue', $stub->getValue()); + + // Lock the field + $stub->lock(); + + // Try to change the value + $stub->setValue('newValue2'); + + // And assert it hasn't changed + $this->assertEquals('newValue', $stub->getValue()); + } + + /** + * @depends testFoundation + */ + public function testErrors() + { + // Create the field + $stub = $this->getMockForAbstractClass(Field::class, ['originalName']); + + // First test the label if none is set + $this->assertEmpty($stub->getErrors()); + + // Set the label + $stub->addError('newError'); + $this->assertEquals(['newError'], $stub->getErrors()); + } + + /** + * @depends testValue, testErrors + */ + public function testBaseValidation() + { + // Create the field + $stub = $this->getMockForAbstractClass(Field::class, ['originalName']); + $stub->expects($this->any())->method("validateField")->will($this->returnValue(true)); + + // And set a value + $stub->setValue('newValue'); + + // Test that the field isn't validated yet + $this->assertFalse($stub->isValidated()); + $this->assertFalse($stub->isValid()); + + // Validate the field + $this->assertTrue($stub->validate()); + + // Assert that all is well + $this->assertTrue($stub->isValidated()); + $this->assertTrue($stub->isValid()); + } + + /** + * @depends testBaseValidation + */ + public function testMissingValue() + { + // Create the field + $stub = $this->getMockForAbstractClass(Field::class, ['originalName']); + $stub->expects($this->any())->method("validateField")->will($this->returnValue(true)); + + // Test that the field isn't validated yet + $this->assertFalse($stub->isValidated()); + $this->assertFalse($stub->isValid()); + + // Validate the field + $this->assertFalse($stub->validate()); + + // Assert that all is wrong + $this->assertTrue($stub->isValidated()); + $this->assertFalse($stub->isValid()); + + // And assert that the error is set + $this->assertEquals([$stub->getLabel() . " may not be empty."], $stub->getErrors()); + } + + /** + * @depends testMissingValue + */ + public function testEmptyErrorString() + { + // Create the field + $stub = $this->getMockForAbstractClass(Field::class, ['originalName']); + $stub->expects($this->any())->method("validateField")->will($this->returnValue(true)); + $stub->emptyErrorString("Value may not be missing."); + + // Test that the field isn't validated yet + $this->assertFalse($stub->isValidated()); + $this->assertFalse($stub->isValid()); + + // Validate the field + $this->assertFalse($stub->validate()); + + // Assert that all is wrong + $this->assertTrue($stub->isValidated()); + $this->assertFalse($stub->isValid()); + + // And assert that the error is set + $this->assertEquals(["Value may not be missing."], $stub->getErrors()); + } + + /** + * @depends testMissingValue + */ + public function testOptionalField() + { + // Create the field + $stub = $this->getMockForAbstractClass(Field::class, ['originalName']); + $stub->expects($this->any())->method("validateField")->will($this->returnValue(true)); + + // Set the field as optional + $stub->optional(); + + // Validate the field + $this->assertTrue($stub->validate()); + + // Assert that all is well + $this->assertTrue($stub->isValidated()); + $this->assertTrue($stub->isValid()); + } + + /** + * @depends testBaseValidation + */ + public function testInvalidField() + { + // Create the field + $stub = $this->getMockForAbstractClass(Field::class, ['originalName']); + + // Stub expects validateField to be called, return true and adds an error to $this->errors[] + $stub->expects($this->any())->method("validateField")->will($this->returnCallback(function() use ($stub) { + $stub->addError("Error"); + return false; + })); + + // And set a value + $stub->setValue('newValue'); + + // Validate the field + $this->assertFalse($stub->validate()); + + // Assert that all is wrong + $this->assertTrue($stub->isValidated()); + $this->assertFalse($stub->isValid()); + + // And assert that the error is set + $this->assertEquals(["Error"], $stub->getErrors()); + } + + /** + * @depends testInvalidField + */ + public function testInvalidate() + { + // Create the field + $stub = $this->getMockForAbstractClass(Field::class, ['originalName']); + $stub->expects($this->any())->method("validateField")->will($this->returnValue(true)); + + // And set a value + $stub->setValue('newValue'); + + // Validate the field + $this->assertTrue($stub->validate()); + + // Assert that all is well + $this->assertTrue($stub->isValidated()); + $this->assertTrue($stub->isValid()); + + // Invalidate the field + $stub->invalidate(); + + // Assert that all is wrong + $this->assertTrue($stub->isValidated()); + $this->assertFalse($stub->isValid()); + } + + /** + * @depends testInvalidField + */ + public function testCondition() + { + // Create the field + $stub = $this->getMockForAbstractClass(Field::class, ['originalName']); + $stub->expects($this->any())->method("validateField")->will($this->returnValue(true)); + + // Set a value + $stub->setValue('newValue'); + + // Add a condition + $stub->condition(function(Field $field) { + $field->addError("Condition error."); + return false; + }); + + // Validate the field + $this->assertFalse($stub->validate()); + + // Assert that all is wrong + $this->assertTrue($stub->isValidated()); + $this->assertFalse($stub->isValid()); + + // And assert that the error is set + $this->assertEquals(["Condition error."], $stub->getErrors()); + } + + /** + * @depends testCondition + */ + public function testValidCondition() + { + // Create the field + $stub = $this->getMockForAbstractClass(Field::class, ['originalName']); + $stub->expects($this->any())->method("validateField")->will($this->returnValue(true)); + + // Set a value + $stub->setValue('newValue'); + + // Add a condition + $stub->condition(function(Field $field) { + return true; + }); + + // Validate the field + $this->assertTrue($stub->validate()); + + // Assert that all is well + $this->assertTrue($stub->isValidated()); + $this->assertTrue($stub->isValid()); + + // And assert that no error is set + $this->assertEquals([], $stub->getErrors()); + } + + /** + * @depends testFoundation + */ + public function testGenerate() + { + // Create the field + $stub = $this->getMockForAbstractClass(Field::class, ['originalName']); + $stub->expects($this->any())->method("generateHtml")->will($this->returnValue("html")); + + // Generate the field + $this->assertEquals("html", $stub->generateHtml()); + $this->assertEquals("html", (string) $stub); + } +} \ No newline at end of file diff --git a/test/base/FormTest.php b/test/base/FormTest.php new file mode 100644 index 0000000..cb5eb68 --- /dev/null +++ b/test/base/FormTest.php @@ -0,0 +1,321 @@ +assertEquals('testName', $form->getName()); + $this->assertEquals('testLabel', $form->getLabel()); + $this->assertInstanceOf(Form::class, $form); + } + + public function testNames() + { + // Set the name originally + $form = new Form('originalName', 'originalLabel'); + $this->assertEquals('originalName', $form->getName()); + + // Change the name + $form->setName('newName'); + $this->assertEquals('newName', $form->getName()); + + // Change the name back + $form->setName('originalName'); + $this->assertEquals('originalName', $form->getName()); + } + + public function testLabels() + { + // Set the label originally + $form = new Form('originalName', 'originalLabel'); + $this->assertEquals('originalLabel', $form->getLabel()); + + // Change the label + $form->setLabel('newLabel'); + $this->assertEquals('newLabel', $form->getLabel()); + + // Change the label back + $form->setLabel('originalLabel'); + $this->assertEquals('originalLabel', $form->getLabel()); + } + + public function testFormErrors() + { + // Generate the original form + $form = new Form('originalName', 'originalLabel'); + $this->assertEquals([], $form->getFormErrors()); + + // Add some errors + $form->addFormError('error1'); + $form->addFormError('error2'); + $this->assertEquals(['error1', 'error2'], $form->getFormErrors()); + + // Add some warnings + $form->addFormWarning('warning1'); + $form->addFormWarning('warning2'); + $this->assertEquals(['warning1', 'warning2'], $form->getFormWarnings()); + } + + /** + * @depends FieldTest::testValidCondition + */ + public function testFields() + { + // Generate the original form + $form = new Form('formName', 'formLabel'); + + // Create a field + $stub = $this->getMockForAbstractClass(Field::class, ['fieldName']); + + // Add the field to the form + $form->field($stub); + + // Check if the field is in the form + $extractedField = $form->getField('fieldName'); + $this->assertEquals($stub, $extractedField); + + // Check the identifier + $this->assertEquals('formName_fieldName', $extractedField->getId()); + + // Check if the field can also be extracted through getFields + $this->assertEquals([$form->getCsrfField(), $stub], $form->getFields()); + } + + /** + * @depends testFields + */ + public function testValidate() + { + // Generate the original form + $form = new Form('formName', 'formLabel'); + + // Create a field + $stub = $this->getMockForAbstractClass(Field::class, ['fieldName']); + $stub->expects($this->any()) + ->method('validateField') + ->will($this->returnValue(true)); + + // Add the field to the form + $form->field($stub); + + // Create a source for input + $form->setSource(function (string $fieldName){ + return match ($fieldName) { + 'fieldName' => 'fieldValue', + default => null, + }; + }); + + // Test that the form isn't validated yet + $this->assertFalse($form->isValidated()); + $this->assertFalse($form->isValid()); + + // And validate + $this->assertTrue($form->validate()); + + // Assert that all is well + $this->assertTrue($form->isValidated()); + $this->assertTrue($form->isValid()); + } + + /** + * @depends testValidate + */ + public function testValidateMissingValues() + { + // generate the original form + $form = new Form('formName', 'formLabel'); + + // Create a field + $stub = $this->getMockForAbstractClass(Field::class, ['fieldName']); + $stub->expects($this->any()) + ->method('validateField') + ->will($this->returnValue(true)); + + // Add the field to the form + $form->field($stub); + + // Test that the form isn't validated yet + $this->assertFalse($form->isValidated()); + $this->assertFalse($form->isValid()); + + // And validate + $this->assertFalse($form->validate()); + + // Assert that all is wrong + $this->assertFalse($form->isValidated()); + $this->assertFalse($form->isValid()); + } + + /** + * @depends testValidateMissingValues + */ + public function testValidateInvalidField() + { + // Create the original form + $form = new Form('formName', 'formLabel'); + + // Create a field + $stub = $this->getMockForAbstractClass(Field::class, ['fieldName']); + $stub->expects($this->any()) + ->method('validateField') + ->will($this->returnCallback(function() use ($stub) { + $stub->addError("Error"); + return false; + })); + + // Add the field to the form + $form->field($stub); + + // Create a source for input + $form->setSource(function (string $fieldName){ + return match ($fieldName) { + 'fieldName' => 'fieldValue', + default => null, + }; + }); + + // Test that the form isn't validated yet + $this->assertFalse($form->isValidated()); + $this->assertFalse($form->isValid()); + + // And validate + $this->assertFalse($form->validate()); + + // Assert that all is wrong + $this->assertTrue($form->isValidated()); + $this->assertFalse($form->isValid()); + + // Assert that the field has an error + $this->assertEquals(['fieldName' => ['Error']], $form->getFieldErrors()); + } + + /** + * @depends testValidateInvalidField + */ + public function testInvalidate() + { + // Create the original form + $form = new Form('formName', 'formLabel'); + + // Create a field + $stub = $this->getMockForAbstractClass(Field::class, ['fieldName']); + $stub->expects($this->any()) + ->method('validateField') + ->will($this->returnValue(true)); + + // Add the field to the form + $form->field($stub); + + // Create a source for input + $form->setSource(function (string $fieldName){ + return match ($fieldName) { + 'fieldName' => 'fieldValue', + default => null, + }; + }); + + // Test that the form isn't validated yet + $this->assertFalse($form->isValidated()); + $this->assertFalse($form->isValid()); + + // And validate + $this->assertTrue($form->validate()); + + // Assert that all is well + $this->assertTrue($form->isValidated()); + $this->assertTrue($form->isValid()); + + // Invalidate the form + $form->invalidate(); + + // Assert that the form is invalidated + $this->assertTrue($form->isValidated()); + $this->assertFalse($form->isValid()); + } + + /** + * @depends testValidateInvalidField + */ + public function testCondition() + { + // Create the original form + $form = new Form('formName', 'formLabel'); + + // Create a field + $stub = $this->getMockForAbstractClass(Field::class, ['fieldName']); + $stub->expects($this->any()) + ->method('validateField') + ->will($this->returnValue(true)); + + // Add the field to the form + $form->field($stub); + + // Create a source for input + $form->setSource(function (string $fieldName){ + return match ($fieldName) { + 'fieldName' => 'fieldValue', + default => null, + }; + }); + + // Add a condition + $form->condition(function (Form $form) { + return false; + }); + + // Test that the form isn't validated yet + $this->assertFalse($form->isValidated()); + $this->assertFalse($form->isValid()); + + // And validate + $this->assertFalse($form->validate()); + + // Assert that all is wrong + $this->assertTrue($form->isValidated()); + $this->assertFalse($form->isValid()); + } + + + +} \ No newline at end of file diff --git a/test/base/LibraryTest.php b/test/base/LibraryTest.php index aa868d1..4974e2d 100644 --- a/test/base/LibraryTest.php +++ b/test/base/LibraryTest.php @@ -34,6 +34,7 @@ * @version Version 1.3.0 */ +use FuzeWorks\Forms\Form; use FuzeWorks\Forms\Forms; use PHPUnit\Framework\TestCase; @@ -53,4 +54,34 @@ class LibraryTest extends TestCase $this->assertInstanceOf(Forms::class, $this->forms); } + // Test prefixes and source directory + public function testPrefixes() + { + $this->assertNull($this->forms->getClassesPrefix()); + $this->assertNull($this->forms->getSourceDirectory()); + } + + public function testGetForm() + { + $form = $this->forms->getForm('testName', 'testLabel'); + $this->assertEquals('testName', $form->getName()); + $this->assertEquals('testLabel', $form->getLabel()); + $this->assertInstanceOf(Form::class, $form); + } + + public function testGetCachedForm() + { + $form = $this->forms->getCachedForm(function (Form $form) { + return $form; + }, 'testName', 'testLabel'); + + $this->assertEquals('testName', $form->getName()); + $this->assertEquals('testLabel', $form->getLabel()); + $this->assertInstanceOf(Form::class, $form); + + // Retrieve the same form again + $form2 = $this->forms->getCachedForm(function (){}, 'testName', 'testLabel'); + $this->assertSame($form, $form2); + } + } \ No newline at end of file diff --git a/test/bootstrap.php b/test/bootstrap.php index 0de88ea..d8a22ce 100644 --- a/test/bootstrap.php +++ b/test/bootstrap.php @@ -48,6 +48,9 @@ $configurator->setLogDirectory(__DIR__ . '/temp'); // Other values $configurator->setTimeZone('Europe/Amsterdam'); +// Add config folder +$configurator->addDirectory(dirname(__FILE__), 'config'); + // Add components $configurator->addComponent(new \FuzeWorks\WebComponent()); $configurator->addComponent(new \FuzeWorks\ObjectStorage\ObjectStorageComponent()); diff --git a/test/config.objectstorage.php b/test/config.objectstorage.php new file mode 100755 index 0000000..c8d41c6 --- /dev/null +++ b/test/config.objectstorage.php @@ -0,0 +1,60 @@ + 'DummyProvider', + 'DummyProvider' => [], + 'RedisProvider' => [ + // Type can be 'tcp' or 'unix' + 'socket_type' => Core::getEnv('OBJECTSTORAGE_REDIS_SOCKET_TYPE', 'tcp'), + // If socket_type == 'unix', set the socket here + 'socket' => Core::getEnv('OBJECTSTORAGE_REDIS_SOCKET', null), + // If socket_type == 'tcp', set the host here + 'host' => Core::getEnv('OBJECTSTORAGE_REDIS_HOST', '127.0.0.1'), + // And some standard settings + 'port' => Core::getEnv('OBJECTSTORAGE_REDIS_PORT', 6379), + 'password' => Core::getEnv('OBJECTSTORAGE_REDIS_PASSWORD', null), + 'timeout' => Core::getEnv('OBJECTSTORAGE_REDIS_TIMEOUT', 0), + 'db_index' => Core::getEnv('OBJECTSTORAGE_REDIS_DBINDEX', 0), + ], + 'FileProvider' => [ + // The directory where objects get stored by the FileProvider + 'storage_directory' => Core::getEnv('OBJECTSTORAGE_FILE_DIRECTORY', Core::$tempDir) + ] +]; \ No newline at end of file