Skip to content

Commit

Permalink
Fix an issue where required rules could not be combined with optional (
Browse files Browse the repository at this point in the history
  • Loading branch information
rubenvanassche committed Oct 4, 2024
1 parent cf86d7a commit c620967
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 4 deletions.
5 changes: 5 additions & 0 deletions src/RuleInferrers/AttributesRuleInferrer.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Spatie\LaravelData\RuleInferrers;

use Spatie\LaravelData\Attributes\Validation\Present;
use Spatie\LaravelData\Attributes\Validation\Sometimes;
use Spatie\LaravelData\Support\DataProperty;
use Spatie\LaravelData\Support\Validation\PropertyRules;
use Spatie\LaravelData\Support\Validation\RequiringRule;
Expand All @@ -29,6 +30,10 @@ public function handle(
$rules->removeType(RequiringRule::class);
}

if ($rule instanceof RequiringRule && $rules->hasType(Sometimes::class)) {
$rules->removeType(Sometimes::class);
}

$rules->add(
...$this->rulesDenormalizer->execute($rule)
);
Expand Down
41 changes: 37 additions & 4 deletions tests/ValidationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1082,18 +1082,26 @@ class CollectionClassC extends Data
->assertRules(
[
'someData' => [
'sometimes',
'array',
'required_without:someOtherData',
],
'someOtherData' => [
'sometimes',
'array',
'required_without:someData',
],
],
[]
);
)
->assertOk([
'someData' => [["string" => "Hello World"]],
])
->assertOk([
'someOtherData' => [["string" => "Hello World"]],
])
->assertOk([
'someData' => [["string" => "Hello World"]],
'someOtherData' => [["string" => "Hello World"]],
])
->assertErrors([]);
});

it('supports required without validation for nullable collections', function () {
Expand Down Expand Up @@ -2429,3 +2437,28 @@ public function __construct(
'some_property' => 1,
]);
})->skip('Validation problem, fix in v5');

it('will remove a sometimes rule generated by an Optional type when manually requiring something', function () {
$dataClass = new class () extends Data {
#[RequiredWith('otherProperty')]
public string|Optional $property;

public string|null $otherProperty;
};

DataValidationAsserter::for($dataClass)
->assertRules([
'property' => ['string', 'required_with:otherProperty'],
'otherProperty' => ['nullable', 'string'],
], ['property' => 'Hello World', 'otherProperty' => 'Hello World'])
->assertOk([
'property' => 'Hello World',
'otherProperty' => 'Hello World',
])
->assertOk([
'otherProperty' => null,
])
->assertErrors([
'otherProperty' => 'Hello World',
]);
});

0 comments on commit c620967

Please sign in to comment.