Skip to content

Commit

Permalink
Merge pull request #11059 from creative-commoners/pulls/5/schema-exce…
Browse files Browse the repository at this point in the history
…ption

ENH Throw exception when no react component
  • Loading branch information
GuySartorelli authored Nov 22, 2023
2 parents cfd8f05 + fdb3299 commit 26c8c0f
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 0 deletions.
21 changes: 21 additions & 0 deletions src/Forms/Schema/FormSchema.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
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.
Expand Down Expand Up @@ -112,9 +113,29 @@ public function getSchema(Form $form)
$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.
*
Expand Down
45 changes: 45 additions & 0 deletions tests/php/Forms/FormSchemaTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
use SilverStripe\Forms\RequiredFields;
use SilverStripe\Forms\FormAction;
use SilverStripe\Forms\PopoverField;
use SilverStripe\Forms\FormField;
use LogicException;

class FormSchemaTest extends SapphireTest
{
Expand All @@ -39,6 +41,49 @@ public function testGetSchema()
$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());
Expand Down

0 comments on commit 26c8c0f

Please sign in to comment.