graphql-platform
graphql-platform copied to clipboard
FilterType<T> has incorrect field definitions
Product
Hot Chocolate
Version
13.9.6
Link to minimal reproduction
https://github.com/wietlol-org/HotChocolateIssues/tree/main/HotChocolateIssues.InvalidFilterType
Steps to reproduce
Run the unit tests in the HotChocolateIssues.FilterInputType project. The test DeleteBooks will fail. After running the tests, the output is written to the TestFiles folder where the erroneous response is presented.
What is expected?
When creating a query/mutation with input according to the following snippet.
[GraphQLType(typeof(FilterInputType<Book>))]
IDictionary<string, object?> filter
The dictionary should only contain the filter as it was specified by the query/mutation input.
What is actually happening?
Instead of only setting the properties that were provided by the input, the current implementation will incorrectly fill almost all fields with the same data.
Given the following input:
mutation {
deleteBooks(
filter: {
title: {eq: "Test"}
}
)
}
The dictionary should only contain an entry for "title", which should be a dictionary only containing an entry for "eq".
Looking at HotChocolate.Types.InputParser.cs
line 255, the data seems correct:
But the resulting value is definitely not:
The reason for this is that the field definitions of the filter type do not have correct index values:
(HotChocolate.Types.InputObjectType.Initialization.cs
line 126)
While their values are being loaded by index:
This means that the resulting dictionary, instead of the following data:
{
"title": {
"eq": "Test"
}
}
will contain the following data:
{
"and": {
"and": "Test",
"or": null,
"eq": "Test",
"neq": "Test",
"contains": "Test",
"ncontains": "Test",
"in": "Test",
"nin": "Test",
"startsWith": "Test",
"nstartsWith": "Test",
"endsWith": "Test",
"nendsWith": "Test"
},
"or": null,
"title": {
"and": "Test",
"or": null,
"eq": "Test",
"neq": "Test",
"contains": "Test",
"ncontains": "Test",
"in": "Test",
"nin": "Test",
"startsWith": "Test",
"nstartsWith": "Test",
"endsWith": "Test",
"nendsWith": "Test"
},
"author": {
"and": "Test",
"or": null,
"eq": "Test",
"neq": "Test",
"contains": "Test",
"ncontains": "Test",
"in": "Test",
"nin": "Test",
"startsWith": "Test",
"nstartsWith": "Test",
"endsWith": "Test",
"nendsWith": "Test"
}
}
Relevant log output
No response
Additional context
The use of [UseFiltering]
is not a valid alternative as these filter fields need to be used in mutations in different places in the input structure.
A good alternative is if a different type than an IDictionary<string, object?>
can be used that is deserialized properly that can be used to filter data (IEnumerables/Lists, IQueryable, etc)
But to the best of my knowledge, there isn't.