From fe7fb48e6e78948dcc2dbdd60a1436cab59c564d Mon Sep 17 00:00:00 2001 From: Danny Foster Date: Tue, 29 Oct 2024 12:13:17 -0500 Subject: [PATCH 1/9] fix: deprecated null subject parameter to `str_replace` Passing null to non-nullable internal function parameters is deprecated in PHP 8.1 --- src/Components/Inputs/Textfield.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Components/Inputs/Textfield.php b/src/Components/Inputs/Textfield.php index 9bbdaec4..02810e25 100644 --- a/src/Components/Inputs/Textfield.php +++ b/src/Components/Inputs/Textfield.php @@ -27,9 +27,11 @@ protected function processValidations(string $fieldKey, string $fieldLabel, mixe $rules->add(new CheckWordCount(CheckWordCount::MODE_MAXIMUM, $this->validation('maxWords'))); } - // PHP needs the regexp armoured with slashes, so... - $pattern = sprintf('/%s/', str_replace('/', '\/', $this->validation('pattern'))); - $rules->addIfNotNull(['regex', $pattern], $this->validation('pattern')); + if ($this->validation('pattern')) { + // PHP needs the regexp armoured with slashes, so... + $pattern = sprintf('/%s/', str_replace('/', '\/', $this->validation('pattern'))); + $rules->add(['regex', $pattern], $this->validation('pattern')); + } return $validator->make( [$fieldKey => $submissionValue], From ba842ffece84abb7d2dd5331e20d6793476aac4b Mon Sep 17 00:00:00 2001 From: Danny Foster Date: Tue, 29 Oct 2024 12:14:08 -0500 Subject: [PATCH 2/9] feat: JSON Logic validation support --- src/Components/BaseComponent.php | 11 + src/Components/ComponentInterface.php | 6 + src/Forms/ValidatedForm.php | 3 + src/Validation/JSONValidation.php | 53 +++ src/Validation/ValidationInterface.php | 11 + .../TestCases/BaseComponentTestCase.php | 2 + tests/Validation/JSONValidationTest.php | 427 ++++++++++++++++++ 7 files changed, 513 insertions(+) create mode 100644 src/Validation/JSONValidation.php create mode 100644 src/Validation/ValidationInterface.php create mode 100644 tests/Validation/JSONValidationTest.php diff --git a/src/Components/BaseComponent.php b/src/Components/BaseComponent.php index 06f26401..6f1d0086 100644 --- a/src/Components/BaseComponent.php +++ b/src/Components/BaseComponent.php @@ -11,6 +11,8 @@ use Northwestern\SysDev\DynamicForms\Conditional\ConditionalInterface; use Northwestern\SysDev\DynamicForms\Conditional\JSONConditional; use Northwestern\SysDev\DynamicForms\Conditional\SimpleConditional; +use Northwestern\SysDev\DynamicForms\Validation\JSONValidation; +use Northwestern\SysDev\DynamicForms\Validation\ValidationInterface; use Northwestern\SysDev\DynamicForms\Errors\CalculationNotImplemented; use Northwestern\SysDev\DynamicForms\Errors\ConditionalNotImplemented; use Northwestern\SysDev\DynamicForms\Errors\InvalidDefinitionError; @@ -282,6 +284,15 @@ public function validations(): array return $this->validations; } + public function advancedValidations(): ?ValidationInterface + { + if ($this->validation('json')) { + return new JSONValidation($this->validation('json')); + } + + return null; + } + public function additional(string $key): mixed { return Arr::get($this->additional, $key); diff --git a/src/Components/ComponentInterface.php b/src/Components/ComponentInterface.php index 15ae3141..10ff3a06 100644 --- a/src/Components/ComponentInterface.php +++ b/src/Components/ComponentInterface.php @@ -5,6 +5,7 @@ use Illuminate\Contracts\Support\MessageBag; use Northwestern\SysDev\DynamicForms\Calculation\CalculationInterface; use Northwestern\SysDev\DynamicForms\Conditional\ConditionalInterface; +use Northwestern\SysDev\DynamicForms\Validation\ValidationInterface; interface ComponentInterface { @@ -140,6 +141,11 @@ public function validation(string $name): mixed; */ public function validations(): array; + /** + * Returns an invokable Validation instance. + */ + public function advancedValidations(): ?ValidationInterface; + /** * Get other settings that are not used directly by the library, but may be present in the component schema. */ diff --git a/src/Forms/ValidatedForm.php b/src/Forms/ValidatedForm.php index d3501d58..3051b5d7 100644 --- a/src/Forms/ValidatedForm.php +++ b/src/Forms/ValidatedForm.php @@ -39,6 +39,9 @@ public function __construct(array $components, array $values) foreach ($this->flatComponents as $component) { $messageBag->merge($component->validate()); + if ($component->advancedValidations()) { + $messageBag->merge($component->advancedValidations()($component, $this->valuesWhileProcessingForm())); + } $transformedValues->put($component->key(), $component->submissionValue()); } diff --git a/src/Validation/JSONValidation.php b/src/Validation/JSONValidation.php new file mode 100644 index 00000000..8a9f77f2 --- /dev/null +++ b/src/Validation/JSONValidation.php @@ -0,0 +1,53 @@ +jsonLogic = JsonLogicHelpers::convertDataVars($jsonLogic); + } + + public function __invoke(ComponentInterface $component, array $submissionValues): MessageBag + { + $bag = new MessageBagImpl; + + if (! $this->isValidCustomValidation($this->jsonLogic)) { + throw new InvalidDefinitionError( + 'Custom JSON Logic validations must always use the "if" parameter. The first argument to the statement must be the "true" case, and the second should be the error to display if the validation fails.', + $component->key(), + ); + } + + $validationResult = JsonLogic::apply($this->jsonLogic, $submissionValues); + + if ($validationResult !== true) { + $bag->add($component->key(), $validationResult); + } + + return $bag; + } + + /** + * Custom JSON Logic validations must always use the "if" parameter. The first argument to the statement + * must be the "true" case, and the second should be the error to display if the validation fails. + * + * {@link https://help.form.io/developers/form-development/form-evaluations#custom-validation-1} + */ + protected function isValidCustomValidation(array $jsonLogic): bool + { + return isset($jsonLogic['if']) && + is_array($jsonLogic['if']) && + count($jsonLogic['if']) === 3; + } +} diff --git a/src/Validation/ValidationInterface.php b/src/Validation/ValidationInterface.php new file mode 100644 index 00000000..5cd85b07 --- /dev/null +++ b/src/Validation/ValidationInterface.php @@ -0,0 +1,11 @@ +assertEquals('foo', $component->defaultValue()); $this->assertNull($component->validation('required')); $this->assertEmpty($component->validations()); + $this->assertNull($component->advancedValidations()); $this->assertTrue($component->additional('disabled')); } diff --git a/tests/Validation/JSONValidationTest.php b/tests/Validation/JSONValidationTest.php new file mode 100644 index 00000000..fa0241ac --- /dev/null +++ b/tests/Validation/JSONValidationTest.php @@ -0,0 +1,427 @@ +clearAll(); + new JSONLogicInitHelper; + + $component = $this->getComponent(validations: $jsonValidation); + + if (is_string($expected) && class_exists($expected)) { + $this->expectException($expected); + } + + $result = $component->advancedValidations()($component, $submissionValues); + + if (empty($expected)) { + $this->assertTrue($result->isEmpty(), 'Expected no validation errors, but some were found.'); + } else { + foreach ($expected as $field => $messages) { + $this->assertTrue( + $result->has($field), + "Expected validation error for field '{$field}'." + ); + foreach ($messages as $message) { + $this->assertContains( + $message, + $result->get($field), + "Expected message '{$message}' for field '{$field}'." + ); + } + } + + $this->assertCount(count($expected), $result->all()); + } + } + + public static function invokeDataProvider(): array + { + return [ + 'should throw exception when "if" parameter is missing' => [ + 'jsonValidation' => json_decode('{ + "json": { + "===": [ + { + "var": "foo" + }, + "bar" + ] + } + }', true), + 'submissionValues' => ['foo' => 'foo'], + 'expected' => InvalidDefinitionError::class, + ], + 'should throw exception when "if" parameter has less than three arguments' => [ + 'jsonValidation' => json_decode('{ + "json": { + "if": [ + { "===": [ { "var": "foo" }, "bar" ] }, + true + ] + } + }', true), + 'submissionValues' => ['foo' => 'baz'], + 'expected' => InvalidDefinitionError::class, + ], + 'should throw exception when "if" parameter has more than three arguments' => [ + 'jsonValidation' => json_decode('{ + "json": { + "if": [ + { "===": [ { "var": "foo" }, "bar" ] }, + true, + "Values must be equal", + "Extra argument" + ] + } + }', true), + 'submissionValues' => ['foo' => 'baz'], + 'expected' => InvalidDefinitionError::class, + ], + 'should throw exception when "if" condition is not an array' => [ + 'jsonValidation' => json_decode('{ + "json": { + "if": "not an array" + } + }', true), + 'submissionValues' => ['foo' => 'baz'], + 'expected' => InvalidDefinitionError::class, + ], + 'should fail when values are not equal with custom message' => [ + 'jsonValidation' => json_decode('{ + "json": { + "if": [ + { "===": [ { "var": "foo" }, "bar" ] }, + true, + "Values must be equal" + ] + } + }', true), + 'submissionValues' => ['foo' => 'foo'], + 'expected' => [ + 'test' => [ + 'Values must be equal', + ], + ], + ], + 'should pass when values are equal' => [ + 'jsonValidation' => json_decode('{ + "json": { + "if": [ + { "===": [ { "var": "foo" }, "bar" ] }, + true, + "Values must be equal" + ] + } + }', true), + 'submissionValues' => ['foo' => 'bar'], + 'expected' => [], + ], + 'should fail when values are equal with custom message' => [ + 'jsonValidation' => json_decode('{ + "json": { + "if": [ + { "!==": [ { "var": "foo" }, "bar" ] }, + true, + "Values must not be equal" + ] + } + }', true), + 'submissionValues' => ['foo' => 'bar'], + 'expected' => [ + 'test' => [ + 'Values must not be equal', + ], + ], + ], + 'should pass when values are not equal' => [ + 'jsonValidation' => json_decode('{ + "json": { + "if": [ + { "!==": [ { "var": "foo" }, "bar" ] }, + true, + "Values must not be equal" + ] + } + }', true), + 'submissionValues' => ['foo' => 'baz'], + 'expected' => [], + ], + 'should fail when value is not in the list with custom message' => [ + 'jsonValidation' => json_decode('{ + "json": { + "if": [ + { "in": [ { "var": "foo" }, ["bar", "baz"] ] }, + true, + "Value must be either bar or baz" + ] + } + }', true), + 'submissionValues' => ['foo' => 'qux'], + 'expected' => [ + 'test' => [ + 'Value must be either bar or baz', + ], + ], + ], + 'should pass when value is in the list' => [ + 'jsonValidation' => json_decode('{ + "json": { + "if": [ + { "in": [ { "var": "foo" }, ["bar", "baz"] ] }, + true, + "Value must be either bar or baz" + ] + } + }', true), + 'submissionValues' => ['foo' => 'bar'], + 'expected' => [], + ], + 'should fail when value is not greater than the threshold with custom message' => [ + 'jsonValidation' => json_decode('{ + "json": { + "if": [ + { ">": [ { "var": "foo" }, 10 ] }, + true, + "Value must be greater than 10" + ] + } + }', true), + 'submissionValues' => ['foo' => 5], + 'expected' => [ + 'test' => [ + 'Value must be greater than 10', + ], + ], + ], + 'should pass when value is greater than the threshold' => [ + 'jsonValidation' => json_decode('{ + "json": { + "if": [ + { ">": [ { "var": "foo" }, 10 ] }, + true, + "Value must be greater than 10" + ] + } + }', true), + 'submissionValues' => ['foo' => 15], + 'expected' => [], + ], + 'should fail when value is not less than the threshold with custom message' => [ + 'jsonValidation' => json_decode('{ + "json": { + "if": [ + { "<": [ { "var": "foo" }, 20 ] }, + true, + "Value must be less than 20" + ] + } + }', true), + 'submissionValues' => ['foo' => 25], + 'expected' => [ + 'test' => [ + 'Value must be less than 20', + ], + ], + ], + 'should pass when value is less than the threshold' => [ + 'jsonValidation' => json_decode('{ + "json": { + "if": [ + { "<": [ { "var": "foo" }, 20 ] }, + true, + "Value must be less than 20" + ] + } + }', true), + 'submissionValues' => ['foo' => 15], + 'expected' => [], + ], + 'should fail multiple fields with custom messages' => [ + 'jsonValidation' => json_decode('{ + "json": { + "if": [ + { "===": [ { "var": "foo" }, "bar" ] }, + true, + "Foo must be equal to bar" + ] + } + }', true), + 'submissionValues' => ['foo' => 'baz'], + 'expected' => [ + 'test' => [ + 'Foo must be equal to bar', + ], + ], + ], + 'should handle nested conditions and fail with custom message' => [ + 'jsonValidation' => json_decode('{ + "json": { + "if": [ + { + "and": [ + { "===": [ { "var": "foo" }, "bar" ] }, + { ">": [ { "var": "baz" }, 10 ] } + ] + }, + true, + "Foo must be bar and baz must be greater than 10" + ] + } + }', true), + 'submissionValues' => ['foo' => 'bar', 'baz' => 5], + 'expected' => [ + 'test' => [ + 'Foo must be bar and baz must be greater than 10', + ], + ], + ], + 'should handle nested conditions and pass when all conditions are met' => [ + 'jsonValidation' => json_decode('{ + "json": { + "if": [ + { + "and": [ + { "===": [ { "var": "foo" }, "bar" ] }, + { ">": [ { "var": "baz" }, 10 ] } + ] + }, + true, + "Foo must be bar and baz must be greater than 10" + ] + } + }', true), + 'submissionValues' => ['foo' => 'bar', 'baz' => 15], + 'expected' => [], + ], + 'should fail when submissionValues is empty' => [ + 'jsonValidation' => json_decode('{ + "json": { + "if": [ + { "===": [ { "var": "foo" }, "bar" ] }, + true, + "Foo must be bar" + ] + } + }', true), + 'submissionValues' => [], + 'expected' => [ + 'test' => [ + 'Foo must be bar', + ], + ], + ], + 'should fail when submissionValues is null' => [ + 'jsonValidation' => json_decode('{ + "json": { + "if": [ + { "===": [ { "var": "foo" }, "bar" ] }, + true, + "Foo must be bar" + ] + } + }', true), + 'submissionValues' => ['foo' => null], + 'expected' => [ + 'test' => [ + 'Foo must be bar', + ], + ], + ], + 'should handle non-string values correctly' => [ + 'jsonValidation' => json_decode('{ + "json": { + "if": [ + { "===": [ { "var": "foo" }, 100 ] }, + true, + "Foo must be 100" + ] + } + }', true), + 'submissionValues' => ['foo' => '100'], + 'expected' => [ + 'test' => [ + 'Foo must be 100', + ], + ], + ], + 'should handle complex logical operators and fail with custom message' => [ + 'jsonValidation' => json_decode('{ + "json": { + "if": [ + { + "and": [ + { "===": [ { "var": "foo" }, "bar" ] }, + { "===": [ { "var": "baz" }, "qux" ] } + ] + }, + true, + "Foo must be bar and Baz must be qux" + ] + } + }', true), + 'submissionValues' => ['foo' => 'bar', 'baz' => 'not_qux'], + 'expected' => [ + 'test' => [ + 'Foo must be bar and Baz must be qux', + ], + ], + ], + 'should handle complex logical operators and pass when all conditions are met' => [ + 'jsonValidation' => json_decode('{ + "json": { + "if": [ + { + "and": [ + { "===": [ { "var": "foo" }, "bar" ] }, + { "===": [ { "var": "baz" }, "qux" ] } + ] + }, + true, + "Foo must be bar and Baz must be qux" + ] + } + }', true), + 'submissionValues' => ['foo' => 'bar', 'baz' => 'qux'], + 'expected' => [], + ], + ]; + } + + private function getComponent( + array $validations = [], + ): ComponentInterface { + /** @var ComponentInterface $component */ + return new Textfield( + key: 'test', + label: 'Test', + errorLabel: null, + components: [], + validations: $validations, + hasMultipleValues: false, + conditional: null, + customConditional: null, + case: 'mixed', + calculateValue: null, + defaultValue: null, + additional: [], + ); + } +} From a89c8efe5b3770536fee926f1cfe2c1328fdaf94 Mon Sep 17 00:00:00 2001 From: Danny Foster Date: Tue, 29 Oct 2024 12:22:00 -0500 Subject: [PATCH 3/9] chore: update `CHANGELOG` --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c2c4b76..b6b28609 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/). ## [Unreleased] +### Breaking Change +- The `ComponentInterface` has a new method, `advancedValidations()` which returns an invokable `ValidationInterface` instance. +### Added +- Support for JSON Logic into the component validation process. ### Fixes - Fixed an issue where the `Currency` component failed validation when not required and given null values. +- Fixed an instance where the `$subject` parameter to `str_replace()` could have been null in `Textfield::processValidations()`, as this was deprecated in PHP 8.1. ## [v1.0.1] 2024-05-15 ### Changed From ebdecd88586b558e9b9cc06f8813383c06af6262 Mon Sep 17 00:00:00 2001 From: dxnter Date: Tue, 29 Oct 2024 17:25:31 +0000 Subject: [PATCH 4/9] Apply php-cs-fixer changes --- src/Components/BaseComponent.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Components/BaseComponent.php b/src/Components/BaseComponent.php index 6f1d0086..a4020961 100644 --- a/src/Components/BaseComponent.php +++ b/src/Components/BaseComponent.php @@ -11,12 +11,12 @@ use Northwestern\SysDev\DynamicForms\Conditional\ConditionalInterface; use Northwestern\SysDev\DynamicForms\Conditional\JSONConditional; use Northwestern\SysDev\DynamicForms\Conditional\SimpleConditional; -use Northwestern\SysDev\DynamicForms\Validation\JSONValidation; -use Northwestern\SysDev\DynamicForms\Validation\ValidationInterface; use Northwestern\SysDev\DynamicForms\Errors\CalculationNotImplemented; use Northwestern\SysDev\DynamicForms\Errors\ConditionalNotImplemented; use Northwestern\SysDev\DynamicForms\Errors\InvalidDefinitionError; use Northwestern\SysDev\DynamicForms\Errors\ValidationNotImplementedError; +use Northwestern\SysDev\DynamicForms\Validation\JSONValidation; +use Northwestern\SysDev\DynamicForms\Validation\ValidationInterface; /** * Implements common functionality for all components. From 82f612982cef310b0e001cd5e201090acf57fd89 Mon Sep 17 00:00:00 2001 From: Danny Foster Date: Tue, 29 Oct 2024 12:28:09 -0500 Subject: [PATCH 5/9] chore: update upgrading guide --- docs/upgrading.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/upgrading.md b/docs/upgrading.md index 4e641da0..7265bd65 100644 --- a/docs/upgrading.md +++ b/docs/upgrading.md @@ -1,5 +1,14 @@ # Upgrading +## v1.1.0 +This version adds a new `advancedValidations()` method to the `ComponentInterface`. + +```php +public function advancedValidations(): ?ValidationInterface; +``` + +If you have implemented this interface, you should update your implementations. + ## v1.0.0 This version swaps to the Formiojs v5 release candidate and assumes Bootstrap v5 and FontAwesome 6 are in use. The package now assumes Laravel 11, Laravel Vite, and PHP 8.2+. From 9f3a6323be74532dd7ece4d87517822737353409 Mon Sep 17 00:00:00 2001 From: Danny Foster Date: Tue, 29 Oct 2024 12:35:02 -0500 Subject: [PATCH 6/9] chore: remove `ray()` call --- tests/Validation/JSONValidationTest.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/Validation/JSONValidationTest.php b/tests/Validation/JSONValidationTest.php index fa0241ac..a64cfd1e 100644 --- a/tests/Validation/JSONValidationTest.php +++ b/tests/Validation/JSONValidationTest.php @@ -14,13 +14,14 @@ */ final class JSONValidationTest extends TestCase { - #[DataProvider('invokeDataProvider')] /** * @param array|class-string $expected + * + * @covers ::isValidCustomValidation */ + #[DataProvider('invokeDataProvider')] public function testInvoke(array $jsonValidation, array $submissionValues, array|string $expected): void { - ray()->clearAll(); new JSONLogicInitHelper; $component = $this->getComponent(validations: $jsonValidation); From 563d0e49bbbc7c87ed49f672b5ed1d44c103b8a1 Mon Sep 17 00:00:00 2001 From: Nick Evans Date: Tue, 29 Oct 2024 13:54:46 -0500 Subject: [PATCH 7/9] Add test for date validation --- tests/Validation/JSONValidationTest.php | 67 +++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/tests/Validation/JSONValidationTest.php b/tests/Validation/JSONValidationTest.php index a64cfd1e..a42a86ae 100644 --- a/tests/Validation/JSONValidationTest.php +++ b/tests/Validation/JSONValidationTest.php @@ -14,6 +14,9 @@ */ final class JSONValidationTest extends TestCase { + private const DATE_EXPECT_FAIL = true; + private const DATE_EXPECT_PASS = false; + /** * @param array|class-string $expected * @@ -56,6 +59,7 @@ public function testInvoke(array $jsonValidation, array $submissionValues, array public static function invokeDataProvider(): array { return [ + ...self::dataFuzzerProvider(), 'should throw exception when "if" parameter is missing' => [ 'jsonValidation' => json_decode('{ "json": { @@ -406,6 +410,69 @@ public static function invokeDataProvider(): array ]; } + public static function dataFuzzerProvider(): array + { + $rule = json_decode('{ + "json": { + "if": [ + { + "<=": [ + { "var": "startsAt" }, + { "var": "endsAt" } + ] + }, + true, + "The absence end date cannot be earlier than the absence start date." + ] + } + }', true); + + return collect([ + // startsAt, endsAt, expectedToFail (bool) + 'should handle dates like the client-side code, fail with custom error message' => [ + '2024-10-05T05:00:00.000000Z', + '2024-10-01T05:00:00.000000Z', + self::DATE_EXPECT_FAIL, + ], + 'should handle dates like the client-side code, pass' => [ + '2024-10-01T05:00:00.000000Z', + '2024-10-05T05:00:00.000000Z', + self::DATE_EXPECT_PASS, + ], + ...collect(range(1, 12))->mapWithKeys(function (int $month) { + $month = str_pad($month, '0', STR_PAD_LEFT); + + return [ + "should handle dates like the client-side code, pass with static low-end date vs 2024-{$month}-XX" => [ + '2024-01-01T05:00:00.000000Z', + "2024-{$month}-05T05:00:00.000000Z", + self::DATE_EXPECT_PASS, + ], + "should handle dates like the client-side code, fail with static low-end date vs 2024-{$month}-XX" => [ + '2024-01-05T05:00:00.000000Z', + "2024-{$month}-02T05:00:00.000000Z", + self::DATE_EXPECT_FAIL, + ], + ]; + })->all(), + 'should handle dates like the client-side code, pass with high month' => [ + '2024-01-01T05:00:00.000000Z', + '2024-10-05T05:00:00.000000Z', + self::DATE_EXPECT_PASS, + ], + ])->map(function (array $data) use ($rule): array { + [$startsAt, $endsAt, $expectedToFail] = $data; + + return [ + 'jsonValidation' => $rule, + 'submissionValues' => ['startsAt' => $startsAt, 'endsAt' => $endsAt], + 'expected' => $expectedToFail + ? ['The absence end date cannot be earlier than the absence start date.'] + : [], + ]; + })->all(); + } + private function getComponent( array $validations = [], ): ComponentInterface { From 396ad7b87c4c84e29b37d34539892bee1973df17 Mon Sep 17 00:00:00 2001 From: Nick Evans Date: Tue, 29 Oct 2024 14:10:42 -0500 Subject: [PATCH 8/9] Fix my tests to make sense --- tests/Validation/JSONValidationTest.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/Validation/JSONValidationTest.php b/tests/Validation/JSONValidationTest.php index a42a86ae..431193ec 100644 --- a/tests/Validation/JSONValidationTest.php +++ b/tests/Validation/JSONValidationTest.php @@ -440,7 +440,7 @@ public static function dataFuzzerProvider(): array self::DATE_EXPECT_PASS, ], ...collect(range(1, 12))->mapWithKeys(function (int $month) { - $month = str_pad($month, '0', STR_PAD_LEFT); + $month = str_pad($month, '1', '0', STR_PAD_LEFT); return [ "should handle dates like the client-side code, pass with static low-end date vs 2024-{$month}-XX" => [ @@ -448,9 +448,9 @@ public static function dataFuzzerProvider(): array "2024-{$month}-05T05:00:00.000000Z", self::DATE_EXPECT_PASS, ], - "should handle dates like the client-side code, fail with static low-end date vs 2024-{$month}-XX" => [ - '2024-01-05T05:00:00.000000Z', + "should handle dates like the client-side code, fail with static high-end date vs 2024-{$month}-XX" => [ "2024-{$month}-02T05:00:00.000000Z", + '2024-01-01T05:00:00.000000Z', self::DATE_EXPECT_FAIL, ], ]; @@ -467,7 +467,7 @@ public static function dataFuzzerProvider(): array 'jsonValidation' => $rule, 'submissionValues' => ['startsAt' => $startsAt, 'endsAt' => $endsAt], 'expected' => $expectedToFail - ? ['The absence end date cannot be earlier than the absence start date.'] + ? ['test' => ['The absence end date cannot be earlier than the absence start date.']] : [], ]; })->all(); From c2b757664bb24c7546c37d29189c4278c911fdb3 Mon Sep 17 00:00:00 2001 From: Nick Evans Date: Tue, 29 Oct 2024 14:14:03 -0500 Subject: [PATCH 9/9] Some docs updates --- docs/index.md | 2 +- docs/upgrading.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/index.md b/docs/index.md index 37dc2daa..068a7431 100644 --- a/docs/index.md +++ b/docs/index.md @@ -33,7 +33,7 @@ There are a couple pieces to be aware of: - **Forms** are shown when you render a form definition. The form can be read-write or read-only (to display a submitted form). Forms produce submissions in the form of key:value JSON documents. ## Supported Features -Formiojs offers a lot of functionality. Dynamic Forms for Laravel has implemented a limited subset of all its available features. +Formiojs offers a lot of functionality. Dynamic Forms for Laravel has implemented a limited subset of all its available features, including JSON Logic support for complex conditions to show/hide fields, calculate values, and validate data. Most of the decisions not to include something were driven by what would give us a good minimum viable product. If there are missing features that you would like to see, please feel free to submit an issue to discuss including it. diff --git a/docs/upgrading.md b/docs/upgrading.md index 7265bd65..b024ed6c 100644 --- a/docs/upgrading.md +++ b/docs/upgrading.md @@ -7,7 +7,7 @@ This version adds a new `advancedValidations()` method to the `ComponentInterfac public function advancedValidations(): ?ValidationInterface; ``` -If you have implemented this interface, you should update your implementations. +This is implemented in the `BaseComponent`. However, if you have implemented this interface elsewhere, you should update your implementations. ## v1.0.0 This version swaps to the Formiojs v5 release candidate and assumes Bootstrap v5 and FontAwesome 6 are in use. The package now assumes Laravel 11, Laravel Vite, and PHP 8.2+.