Skip to content

Commit feae922

Browse files
Remove validator, change code behaviour (#51)
* Remove validator, change code behaviour * Update AppAny.HotChocolate.FluentValidation.csproj * Refactor extensions, generalize UseValidator * Update README.md * Update README.md * Add null input with validation strategy test * Add AssertDefaultErrorMapper * Add AssertSuceessResult * Remove assert single * Update ci to semver release-first
1 parent 5a695bd commit feae922

26 files changed

Lines changed: 1465 additions & 1671 deletions

.github/workflows/package.yaml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: Package
2+
3+
on:
4+
release:
5+
types: [created]
6+
7+
jobs:
8+
release:
9+
name: Package
10+
runs-on: ubuntu-20.04
11+
12+
steps:
13+
- name: Package | Checkout
14+
uses: actions/checkout@v2.3.4
15+
16+
- name: Package | Release
17+
id: release
18+
uses: tenhaus/get-release-or-tag@v2
19+
20+
- name: Package | Setup
21+
uses: actions/setup-dotnet@v1.7.2
22+
with:
23+
dotnet-version: 5.0.x
24+
25+
- name: Package | Publish
26+
id: publish
27+
uses: brandedoutcast/publish-nuget@v2.5.5
28+
with:
29+
NUGET_KEY: ${{ secrets.NUGET_API_KEY }}
30+
PROJECT_FILE_PATH: src/AppAny.HotChocolate.FluentValidation.csproj
31+
VERSION_STATIC: ${{ steps.release.outputs.tag }}
32+
TAG_FORMAT: '*'
33+
INCLUDE_SYMBOLS: true
34+

.github/workflows/release.yaml

Lines changed: 16 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ on:
66
release:
77
description: Release
88
required: true
9+
default: patch
910

1011
jobs:
1112
release:
@@ -16,46 +17,24 @@ jobs:
1617
- name: Release | Checkout
1718
uses: actions/checkout@v2.3.4
1819

19-
- name: Release | Setup
20-
uses: actions/setup-dotnet@v1.7.2
20+
- name: Release | Previous | Cancel
21+
uses: styfle/cancel-workflow-action@0.8.0
2122
with:
22-
dotnet-version: 5.0.x
23+
access_token: ${{ secrets.UPDATE_WORKFLOWS_TOKEN }}
2324

24-
- name: Release
25-
id: release
26-
uses: actions/create-release@v1.1.4
27-
env:
28-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
25+
- name: Release | Tag
26+
id: tag
27+
uses: zwaldowski/semver-release-action@v1
2928
with:
30-
tag_name: ${{ github.event.inputs.release }}
31-
release_name: ${{ github.event.inputs.release }}
32-
33-
- name: Release | Publish
34-
id: publish
35-
uses: brandedoutcast/publish-nuget@v2.5.5
36-
with:
37-
NUGET_KEY: ${{ secrets.NUGET_API_KEY }}
38-
PROJECT_FILE_PATH: src/AppAny.HotChocolate.FluentValidation.csproj
39-
VERSION_STATIC: ${{ github.event.inputs.release }}
40-
TAG_FORMAT: '*'
41-
INCLUDE_SYMBOLS: true
42-
43-
- name: Release | Assets
44-
uses: actions/upload-release-asset@v1.0.2
29+
bump: ${{ github.event.inputs.release }}
30+
github_token: ${{ secrets.UPDATE_WORKFLOWS_TOKEN }}
4531
env:
46-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
47-
with:
48-
upload_url: ${{ steps.release.outputs.upload_url }}
49-
asset_name: ${{ steps.publish.outputs.PACKAGE_NAME }}
50-
asset_path: ${{ steps.publish.outputs.PACKAGE_PATH }}
51-
asset_content_type: application/zip
32+
ACTIONS_ALLOW_UNSECURE_COMMANDS: true
5233

53-
- name: Release | Assets | Symbols
54-
uses: actions/upload-release-asset@v1.0.2
55-
env:
56-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
34+
- name: Release
35+
uses: actions/create-release@v1.1.4
5736
with:
58-
upload_url: ${{ steps.release.outputs.upload_url }}
59-
asset_name: ${{ steps.publish.outputs.SYMBOLS_PACKAGE_NAME }}
60-
asset_path: ${{ steps.publish.outputs.SYMBOLS_PACKAGE_PATH }}
61-
asset_content_type: application/zip
37+
tag_name: ${{ steps.tag.outputs.version }}
38+
release_name: ${{ steps.tag.outputs.version }}
39+
env:
40+
GITHUB_TOKEN: ${{ secrets.UPDATE_WORKFLOWS_TOKEN }}

README.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ public class ExampleInputValidator : AbstractValidator<ExampleInput>
4343
{
4444
public ExampleInputValidator()
4545
{
46-
RuleFor(input => input.Example)
46+
RuleFor(input => input.ExampleProperty)
4747
.NotEmpty()
48-
.WithMessage("Example is empty");
48+
.WithMessage("Property is empty");
4949
}
5050
}
5151
```
@@ -93,7 +93,6 @@ descriptor.Field(x => x.Example(default!))
9393
... Example([UseFluentValidation, UseValidator((typeof(ExampleInputValidator))] ExampleInput input) { ... }
9494
```
9595

96-
9796
## 📝 Docs 📝
9897

9998
- 📄 [Abstractions](docs/core-abstractions.md)

docs/examples/error-mappers.md

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,36 @@
55
- All extension methods has overrides to pass more error mappers
66
- All error mappers can be composed with other
77

8+
```cs
9+
public class NotEmptyNameValidator : AbstractValidator<ExampleInput>
10+
{
11+
public NotEmptyNameValidator()
12+
{
13+
RuleFor(input => input.ExampleProperty)
14+
.NotEmpty()
15+
.WithMessage("Property is empty")
16+
.WithErrorCode("ERR0123");
17+
}
18+
}
19+
```
20+
821
## .UseDefaultErrorMapper()
922

1023
```json
1124
{
1225
"errors": [
1326
{
14-
"message": "Name is empty",
27+
"message": "Property is empty",
1528
"path": [
16-
"createUser"
29+
"example"
1730
],
1831
"extensions": {
19-
"code": "ValidationFailed"
32+
"code": "ERR0123"
2033
}
2134
}
2235
],
2336
"data": {
24-
"createUser": null
37+
"example": null
2538
}
2639
}
2740
```
@@ -32,22 +45,21 @@
3245
{
3346
"errors": [
3447
{
35-
"message": "Name is empty",
48+
"message": "Property is empty",
3649
"path": [
37-
"createUser"
50+
"example"
3851
],
3952
"extensions": {
40-
"code": "ValidationFailed",
41-
"validator": "NotEmptyValidator",
42-
"field": "createUser",
53+
"code": "ERR0123",
54+
"field": "example",
4355
"argument": "input",
44-
"property": "Name",
56+
"property": "ExampleProperty",
4557
"severity": "Error"
4658
}
4759
}
4860
],
4961
"data": {
50-
"createUser": null
62+
"example": null
5163
}
5264
}
5365
```
@@ -58,28 +70,27 @@
5870
{
5971
"errors": [
6072
{
61-
"message": "Name is empty",
73+
"message": "Property is empty",
6274
"path": [
63-
"createUser"
75+
"example"
6476
],
6577
"extensions": {
66-
"code": "ValidationFailed",
67-
"validator": "NotEmptyValidator",
68-
"field": "createUser",
78+
"code": "ERR0123",
79+
"field": "example",
6980
"argument": "input",
70-
"property": "Name",
81+
"property": "ExampleProperty",
7182
"severity": "Error",
7283
"attemptedValue": "",
7384
"customState": null,
7485
"formattedMessagePlaceholderValues": {
75-
"PropertyName": "Name",
86+
"PropertyName": "ExampleProperty",
7687
"PropertyValue": ""
7788
}
7889
}
7990
}
8091
],
8192
"data": {
82-
"createUser": null
93+
"example": null
8394
}
8495
}
8596
```

src/AppAny.HotChocolate.FluentValidation.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<PropertyGroup>
44
<TargetFramework>netstandard2.0</TargetFramework>
55
<Nullable>enable</Nullable>
6-
<Version>0.1.18</Version>
6+
<Version>0.1.19</Version>
77
<LangVersion>9</LangVersion>
88
<EmbedUntrackedSources>true</EmbedUntrackedSources>
99
<IncludeSymbols>true</IncludeSymbols>

src/Builders/Extensions/UseValidationStrategyExtensions.cs

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
using System;
2+
using FluentValidation;
23
using FluentValidation.Internal;
4+
using FluentValidation.Results;
5+
using Microsoft.Extensions.DependencyInjection;
36

47
namespace AppAny.HotChocolate.FluentValidation
58
{
@@ -42,9 +45,47 @@ public static ArgumentValidationBuilder UseValidationStrategy<TInput>(
4245
this ArgumentValidationBuilder builder,
4346
Action<InputValidatorContext, ValidationStrategy<TInput>> validationStrategy)
4447
{
45-
return builder.UseInputValidators(context => ValidationDefaults.InputValidators.WithStrategy<TInput>(
46-
context,
47-
strategy => validationStrategy(context, strategy)));
48+
return builder.UseInputValidators(async inputValidatorContext =>
49+
{
50+
var argumentValue = inputValidatorContext
51+
.MiddlewareContext
52+
.ArgumentValue<TInput>(inputValidatorContext.Argument.Name);
53+
54+
if (argumentValue is null)
55+
{
56+
return null;
57+
}
58+
59+
var validatorType = inputValidatorContext.Argument.GetGenericValidatorType();
60+
61+
var validators = (IValidator[])inputValidatorContext.MiddlewareContext.Services.GetServices(validatorType);
62+
63+
var validationContext = ValidationContext<TInput>.CreateWithOptions(
64+
argumentValue,
65+
strategy => validationStrategy(inputValidatorContext, strategy));
66+
67+
ValidationResult? validationResult = null;
68+
69+
for (var validatorIndex = 0; validatorIndex < validators.Length; validatorIndex++)
70+
{
71+
var validator = validators[validatorIndex];
72+
73+
var validatorResult = await validator
74+
.ValidateAsync(validationContext, inputValidatorContext.MiddlewareContext.RequestAborted)
75+
.ConfigureAwait(false);
76+
77+
if (validationResult is null)
78+
{
79+
validationResult = validatorResult;
80+
}
81+
else
82+
{
83+
validationResult.MergeFailures(validatorResult);
84+
}
85+
}
86+
87+
return validationResult;
88+
});
4889
}
4990
}
5091
}

0 commit comments

Comments
 (0)