Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Validation attributes #901

Merged
merged 6 commits into from
May 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ CHANGELOG

### Added
- Add support to use array in `controller` param in config [\#906 / viktorruskai](https://github.com/rebing/graphql-laravel/pull/906)
- Add support for laravel validation attributes [\#901 / jacobdekeizer](https://github.com/rebing/graphql-laravel/pull/901)

### Fixed
- Allow 'always' to work on object types [\#473 / tinyoverflow \#369 / zjbarg](https://github.com/rebing/graphql-laravel/pull/892)
Expand Down
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ The default GraphiQL view makes use of the global `csrf_token()` helper function
- [Example using Laravel's validator directly](#example-using-laravels-validator-directly)
- [Handling validation errors](#handling-validation-errors)
- [Customizing error messages](#customizing-error-messages)
- [Customizing attributes](#customizing-attributes)
- [Misc notes](#misc-notes)
- [Resolve method](#resolve-method)
- [Resolver middleware](#resolver-middleware)
Expand Down Expand Up @@ -993,6 +994,21 @@ public function validationErrorMessages(array $args = []): array
}
```

#### Customizing attributes

The validation attributes can be customised by overriding the
`validationAttributes` method. This method should return an array of custom
attributes in the same way documented by Laravel's validation.

```php
public function validationAttributes(array $args = []): array
{
return [
'email' => 'email address',
];
}
```

#### Misc notes

Certain type declarations of GraphQL may cancel our or render certain validations
Expand Down
5 changes: 5 additions & 0 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -1395,6 +1395,11 @@ parameters:
count: 14
path: tests/Unit/MutationTest.php

-
message: "#^Relation 'test_validation_custom_attributes' is not found in Illuminate\\\\Contracts\\\\Support\\\\MessageBag model\\.$#"
count: 7
path: tests/Unit/MutationTest.php

-
message: "#^Relation 'test_with_rules_non_nullable_list_of_non_nullable_input_object' is not found in Illuminate\\\\Contracts\\\\Support\\\\MessageBag model\\.$#"
count: 3
Expand Down
16 changes: 15 additions & 1 deletion src/Support/Field.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,17 @@ public function validationErrorMessages(array $args = []): array
return [];
}

/**
* Define custom Laravel Validator attributes as per Laravel 'custom attributes'.
*
* @param array<string,mixed> $args submitted arguments
* @return array<string,string>
*/
public function validationAttributes(array $args = []): array
{
return [];
}

/**
* @param array<string,mixed> $args
* @return array<string,mixed>
Expand Down Expand Up @@ -120,7 +131,10 @@ public function getValidator(array $args, array $rules): ValidatorContract
// allow our error messages to be customised
$messages = $this->validationErrorMessages($args);

return Validator::make($args, $rules, $messages);
// allow our attributes to be customized
$attributes = $this->validationAttributes($args);

return Validator::make($args, $rules, $messages, $attributes);
}

/**
Expand Down
13 changes: 13 additions & 0 deletions tests/Support/Objects/UpdateExampleMutationWithInputType.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,19 @@ public function args(): array
'name' => 'test',
'type' => Type::nonNull(Type::listOf(Type::nonNull(GraphQL::type('ExampleValidationInputObject')))),
],

'test_validation_custom_attributes' => [
'name' => 'custom validation attributes',
'type' => Type::string(),
'rules' => ['required'],
],
];
}

public function validationAttributes(array $args = []): array
{
return [
'test_validation_custom_attributes' => 'custom attribute',
];
}

Expand Down
42 changes: 35 additions & 7 deletions tests/Unit/MutationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ public function testResolve(): void
['email' => '[email protected]'],
],
],
'test_validation_custom_attributes' => 'test',
], [], $this->resolveInfoMock());
}

Expand Down Expand Up @@ -117,7 +118,8 @@ public function testValidationError(): void
self::assertTrue($messages->has('test_with_rules_non_nullable_input_object.otherValue'));
self::assertTrue($messages->has('test_with_rules_non_nullable_input_object.nest'));
self::assertTrue($messages->has('test_with_rules_non_nullable_input_object.list'));
self::assertCount(6, $messages->all());
self::assertTrue($messages->has('test_validation_custom_attributes'));
self::assertCount(7, $messages->all());
}

public function testWithInput(): void
Expand Down Expand Up @@ -154,7 +156,8 @@ public function testWithInput(): void
self::assertTrue($messages->has('test_with_rules_non_nullable_input_object.otherValue'));
self::assertTrue($messages->has('test_with_rules_non_nullable_input_object.nest'));
self::assertTrue($messages->has('test_with_rules_non_nullable_input_object.list'));
self::assertCount(6, $messages->all());
self::assertTrue($messages->has('test_validation_custom_attributes'));
self::assertCount(7, $messages->all());
}

public function testWithEmptyInput(): void
Expand Down Expand Up @@ -182,7 +185,8 @@ public function testWithEmptyInput(): void
self::assertTrue($messages->has('test_with_rules'));
self::assertTrue($messages->has('test_with_rules_non_nullable_input_object'));
self::assertTrue($messages->has('test_with_rules_closure'));
self::assertCount(4, $messages->all());
self::assertTrue($messages->has('test_validation_custom_attributes'));
self::assertCount(5, $messages->all());
}

public function testWithInputDepthOne(): void
Expand Down Expand Up @@ -212,7 +216,8 @@ public function testWithInputDepthOne(): void

self::assertTrue($messages->has('test_with_rules_non_nullable_input_object'));
self::assertTrue($messages->has('test_with_rules_closure'));
self::assertCount(3, $messages->all());
self::assertTrue($messages->has('test_validation_custom_attributes'));
self::assertCount(4, $messages->all());
}

public function testWithInputWithEmptyInputObjects(): void
Expand Down Expand Up @@ -245,6 +250,8 @@ public function testWithInputWithEmptyInputObjects(): void

self::assertTrue($messages->has('test_with_rules'));

self::assertTrue($messages->has('test_validation_custom_attributes'));

self::assertTrue($messages->has('test_with_rules_nullable_input_object.otherValue'));
self::assertTrue($messages->has('test_with_rules_nullable_input_object.val'));
self::assertTrue($messages->has('test_with_rules_nullable_input_object.nest'));
Expand All @@ -253,7 +260,7 @@ public function testWithInputWithEmptyInputObjects(): void
self::assertTrue($messages->has('test_with_rules_non_nullable_input_object.val'));
self::assertTrue($messages->has('test_with_rules_non_nullable_input_object.nest'));
self::assertTrue($messages->has('test_with_rules_non_nullable_input_object.list'));
self::assertCount(12, $messages->all());
self::assertCount(13, $messages->all());
}

public function testWithEmptyArrayOfInputsObjects(): void
Expand Down Expand Up @@ -282,7 +289,8 @@ public function testWithEmptyArrayOfInputsObjects(): void
self::assertTrue($messages->has('test_with_rules'));
self::assertTrue($messages->has('test_with_rules_non_nullable_input_object'));
self::assertTrue($messages->has('test_with_rules_closure'));
self::assertCount(4, $messages->all());
self::assertTrue($messages->has('test_validation_custom_attributes'));
self::assertCount(5, $messages->all());
}

public function testWithArrayOfInputsObjects(): void
Expand Down Expand Up @@ -319,7 +327,8 @@ public function testWithArrayOfInputsObjects(): void
self::assertTrue($messages->has('test_with_rules_non_nullable_list_of_non_nullable_input_object.0.otherValue'));
self::assertTrue($messages->has('test_with_rules_non_nullable_list_of_non_nullable_input_object.0.nest'));
self::assertTrue($messages->has('test_with_rules_non_nullable_list_of_non_nullable_input_object.0.list'));
self::assertCount(7, $messages->all());
self::assertTrue($messages->has('test_validation_custom_attributes'));
self::assertCount(8, $messages->all());
}

public function testCustomValidationErrorMessages(): void
Expand Down Expand Up @@ -356,6 +365,25 @@ public function testCustomValidationErrorMessages(): void
);
}

public function testCustomValidationAttributes(): void
{
$class = $this->getFieldClass();
$field = new $class();
$attributes = $field->getAttributes();

/** @var ValidationError $exception */
$exception = null;

try {
$attributes['resolve'](null, [], [], $this->resolveInfoMock());
} catch (ValidationError $exception) {
}

$messages = $exception->getValidatorMessages();

self::assertEquals('The custom attribute field is required.', $messages->first('test_validation_custom_attributes'));
}

public function testRuleCallbackArgumentsMatchesTheInput(): void
{
$this->expectException(ValidationError::class);
Expand Down