mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
NEW Add FieldsValidator to ensure fields get validated
This commit is contained in:
parent
2a56cc3ea4
commit
5a52484d88
26
src/Forms/FieldsValidator.php
Normal file
26
src/Forms/FieldsValidator.php
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\Forms;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates the internal state of all fields in the form.
|
||||||
|
*/
|
||||||
|
class FieldsValidator extends Validator
|
||||||
|
{
|
||||||
|
public function php($data): bool
|
||||||
|
{
|
||||||
|
$valid = true;
|
||||||
|
$fields = $this->form->Fields();
|
||||||
|
|
||||||
|
foreach ($fields as $field) {
|
||||||
|
$valid = ($field->validate($this) && $valid);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function canBeCached(): bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -16,6 +16,7 @@ use SilverStripe\Forms\FieldList;
|
|||||||
use SilverStripe\Forms\FormField;
|
use SilverStripe\Forms\FormField;
|
||||||
use SilverStripe\Forms\FormScaffolder;
|
use SilverStripe\Forms\FormScaffolder;
|
||||||
use SilverStripe\Forms\CompositeValidator;
|
use SilverStripe\Forms\CompositeValidator;
|
||||||
|
use SilverStripe\Forms\FieldsValidator;
|
||||||
use SilverStripe\Forms\HiddenField;
|
use SilverStripe\Forms\HiddenField;
|
||||||
use SilverStripe\i18n\i18n;
|
use SilverStripe\i18n\i18n;
|
||||||
use SilverStripe\i18n\i18nEntityProvider;
|
use SilverStripe\i18n\i18nEntityProvider;
|
||||||
@ -2600,7 +2601,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
*/
|
*/
|
||||||
public function getCMSCompositeValidator(): CompositeValidator
|
public function getCMSCompositeValidator(): CompositeValidator
|
||||||
{
|
{
|
||||||
$compositeValidator = CompositeValidator::create();
|
$compositeValidator = CompositeValidator::create([FieldsValidator::create()]);
|
||||||
|
|
||||||
// Support for the old method during the deprecation period
|
// Support for the old method during the deprecation period
|
||||||
if ($this->hasMethod('getCMSValidator')) {
|
if ($this->hasMethod('getCMSValidator')) {
|
||||||
|
@ -6,6 +6,7 @@ use Behat\Behat\Context\Context;
|
|||||||
use Behat\Behat\Hook\Scope\AfterStepScope;
|
use Behat\Behat\Hook\Scope\AfterStepScope;
|
||||||
use Behat\Mink\Element\Element;
|
use Behat\Mink\Element\Element;
|
||||||
use Behat\Mink\Element\NodeElement;
|
use Behat\Mink\Element\NodeElement;
|
||||||
|
use Behat\Mink\Exception\ElementNotFoundException;
|
||||||
use Behat\Mink\Selector\Xpath\Escaper;
|
use Behat\Mink\Selector\Xpath\Escaper;
|
||||||
use Behat\Mink\Session;
|
use Behat\Mink\Session;
|
||||||
use PHPUnit\Framework\Assert;
|
use PHPUnit\Framework\Assert;
|
||||||
@ -86,20 +87,30 @@ class CmsUiContext implements Context
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Then /^I should see a "(.+)" (\w+) toast$/
|
* @Then /^I should (not |)see a "(.+)" (\w+) toast$/
|
||||||
*/
|
*/
|
||||||
public function iShouldSeeAToast($notice, $type)
|
public function iShouldSeeAToast($not, $notice, $type)
|
||||||
{
|
{
|
||||||
|
if ($not) {
|
||||||
|
try {
|
||||||
|
// If there is a toast of that type, ensure it doesn't contain the notice.
|
||||||
|
$this->getMainContext()->assertElementNotContains('.toast--' . $type, $notice);
|
||||||
|
} catch (ElementNotFoundException $e) {
|
||||||
|
// no-op - if the element doesn't exist at all, then that passes the test.
|
||||||
|
}
|
||||||
|
} else {
|
||||||
$this->getMainContext()->assertElementContains('.toast--' . $type, $notice);
|
$this->getMainContext()->assertElementContains('.toast--' . $type, $notice);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Then /^I should see a "(.+)" (\w+) toast with these actions: (.+)$/
|
* @Then /^I should (not |)see a "(.+)" (\w+) toast with these actions: (.+)$/
|
||||||
*/
|
*/
|
||||||
public function iShouldSeeAToastWithAction($notice, $type, $actions)
|
public function iShouldSeeAToastWithAction($not, $notice, $type, $actions)
|
||||||
{
|
{
|
||||||
$this->iShouldSeeAToast($notice, $type);
|
$this->iShouldSeeAToast($not, $notice, $type);
|
||||||
|
|
||||||
|
if (!$not) {
|
||||||
$actions = explode(',', $actions ?? '');
|
$actions = explode(',', $actions ?? '');
|
||||||
foreach ($actions as $order => $action) {
|
foreach ($actions as $order => $action) {
|
||||||
$this->getMainContext()->assertElementContains(
|
$this->getMainContext()->assertElementContains(
|
||||||
@ -108,6 +119,7 @@ class CmsUiContext implements Context
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $action
|
* @param $action
|
||||||
|
79
tests/php/Forms/FieldsValidatorTest.php
Normal file
79
tests/php/Forms/FieldsValidatorTest.php
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\Forms\Tests;
|
||||||
|
|
||||||
|
use SilverStripe\Dev\SapphireTest;
|
||||||
|
use SilverStripe\Forms\EmailField;
|
||||||
|
use SilverStripe\Forms\FieldList;
|
||||||
|
use SilverStripe\Forms\FieldsValidator;
|
||||||
|
use SilverStripe\Forms\Form;
|
||||||
|
|
||||||
|
class FieldsValidatorTest extends SapphireTest
|
||||||
|
{
|
||||||
|
protected $usesDatabase = false;
|
||||||
|
|
||||||
|
public function provideValidation()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'missing values arent invalid' => [
|
||||||
|
'values' => [],
|
||||||
|
'isValid' => true,
|
||||||
|
],
|
||||||
|
'empty values arent invalid' => [
|
||||||
|
'values' => [
|
||||||
|
'EmailField1' => '',
|
||||||
|
'EmailField2' => null,
|
||||||
|
],
|
||||||
|
'isValid' => true,
|
||||||
|
],
|
||||||
|
'any invalid is invalid' => [
|
||||||
|
'values' => [
|
||||||
|
'EmailField1' => 'email@example.com',
|
||||||
|
'EmailField2' => 'not email',
|
||||||
|
],
|
||||||
|
'isValid' => false,
|
||||||
|
],
|
||||||
|
'all invalid is invalid' => [
|
||||||
|
'values' => [
|
||||||
|
'EmailField1' => 'not email',
|
||||||
|
'EmailField2' => 'not email',
|
||||||
|
],
|
||||||
|
'isValid' => false,
|
||||||
|
],
|
||||||
|
'all valid is valid' => [
|
||||||
|
'values' => [
|
||||||
|
'EmailField1' => 'email@example.com',
|
||||||
|
'EmailField2' => 'email@example.com',
|
||||||
|
],
|
||||||
|
'isValid' => true,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider provideValidation
|
||||||
|
*/
|
||||||
|
public function testValidation(array $values, bool $isValid)
|
||||||
|
{
|
||||||
|
$fieldList = new FieldList([
|
||||||
|
$field1 = new EmailField('EmailField1'),
|
||||||
|
$field2 = new EmailField('EmailField2'),
|
||||||
|
]);
|
||||||
|
if (array_key_exists('EmailField1', $values)) {
|
||||||
|
$field1->setValue($values['EmailField1']);
|
||||||
|
}
|
||||||
|
if (array_key_exists('EmailField2', $values)) {
|
||||||
|
$field2->setValue($values['EmailField2']);
|
||||||
|
}
|
||||||
|
$form = new Form(null, 'testForm', $fieldList, new FieldList([/* no actions */]), new FieldsValidator());
|
||||||
|
|
||||||
|
$result = $form->validationResult();
|
||||||
|
$this->assertSame($isValid, $result->isValid());
|
||||||
|
$messages = $result->getMessages();
|
||||||
|
if ($isValid) {
|
||||||
|
$this->assertEmpty($messages);
|
||||||
|
} else {
|
||||||
|
$this->assertNotEmpty($messages);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -290,10 +290,11 @@ class GroupTest extends FunctionalTest
|
|||||||
|
|
||||||
$newGroup = new Group();
|
$newGroup = new Group();
|
||||||
|
|
||||||
$validators = $newGroup->getCMSCompositeValidator()->getValidators();
|
$validators = $newGroup->getCMSCompositeValidator()->getValidatorsByType(RequiredFields::class);
|
||||||
$this->assertCount(1, $validators);
|
$this->assertCount(1, $validators);
|
||||||
$this->assertInstanceOf(RequiredFields::class, $validators[0]);
|
$validator = array_shift($validators);
|
||||||
$this->assertTrue(in_array('Title', $validators[0]->getRequired() ?? []));
|
$this->assertInstanceOf(RequiredFields::class, $validator);
|
||||||
|
$this->assertTrue(in_array('Title', $validator->getRequired() ?? []));
|
||||||
|
|
||||||
$newGroup->Title = $group1->Title;
|
$newGroup->Title = $group1->Title;
|
||||||
$result = $newGroup->validate();
|
$result = $newGroup->validate();
|
||||||
|
Loading…
Reference in New Issue
Block a user