ENH Throw exception when no react component

This commit is contained in:
Steve Boyd 2023-11-22 14:17:47 +13:00
parent cfd8f05a04
commit fdb329913c
2 changed files with 66 additions and 0 deletions

View File

@ -9,6 +9,7 @@ use SilverStripe\Forms\CompositeField;
use SilverStripe\Forms\Form;
use SilverStripe\Forms\FormField;
use SilverStripe\ORM\ValidationResult;
use LogicException;
/**
* Represents a {@link Form} as structured data which allows a frontend library to render it.
@ -112,9 +113,29 @@ class FormSchema
$schema['fields'][] = $field->getSchemaData();
}
// Validate there are react components for all fields
// Note 'actions' (FormActions) are always valid because FormAction.schemaComponent has a default value
$this->recursivelyValidateSchemaData($schema['fields']);
return $schema;
}
private function recursivelyValidateSchemaData(array $schemaData)
{
foreach ($schemaData as $data) {
if (!$data['schemaType'] && !$data['component']) {
$name = $data['name'];
$message = "Could not find a react component for field \"$name\"."
. "Replace or remove the field instance from the field list,"
. ' or update the field class and set the schemaDataType or schemaComponent property.';
throw new LogicException($message);
}
if (array_key_exists('children', $data)) {
$this->recursivelyValidateSchemaData($data['children']);
}
}
}
/**
* Gets the current state of this form as a nested array.
*

View File

@ -14,6 +14,8 @@ use SilverStripe\Forms\TextField;
use SilverStripe\Forms\RequiredFields;
use SilverStripe\Forms\FormAction;
use SilverStripe\Forms\PopoverField;
use SilverStripe\Forms\FormField;
use LogicException;
class FormSchemaTest extends SapphireTest
{
@ -39,6 +41,49 @@ class FormSchemaTest extends SapphireTest
$this->assertEquals($expected, $schema);
}
/**
* @dataProvider provideGetSchemaException
*/
public function testGetSchemaException(string $field, bool $expectException): void
{
$fields = [];
if ($field === '<HasComponent>') {
$fields[] = (new FormField('TestField'))->setSchemaComponent('MyPretendComponent');
} elseif ($field === '<HasDataType>') {
$fields[] = new class('TestField') extends FormField {
protected $schemaDataType = FormField::SCHEMA_DATA_TYPE_CUSTOM;
};
} elseif ($field === '<None>') {
$fields[] = new FormField('TestField');
}
$form = new Form(null, 'TestForm', new FieldList($fields));
$formSchema = new FormSchema($form);
if ($expectException) {
$this->expectException(LogicException::class);
} else {
$this->expectNotToPerformAssertions();
}
$formSchema->getSchema($form);
}
public function provideGetSchemaException(): array
{
return [
[
'field' => '<HasComponent>',
'expectException' => false,
],
[
'field' => '<HasDataType>',
'expectException' => false,
],
[
'field' => '<None>',
'expectException' => true,
],
];
}
public function testGetState()
{
$form = new Form(null, 'TestForm', new FieldList(), new FieldList());