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

allow to set custom filter handler #2563

Merged
merged 9 commits into from
Nov 17, 2020
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ namespace HotChocolate.Data.Filters
public class FilterTypeInterceptor
: TypeInterceptor
{
private readonly Dictionary<string, IFilterConvention> _conventions
= new Dictionary<string, IFilterConvention>();
private readonly Dictionary<string, IFilterConvention> _conventions =
new Dictionary<string, IFilterConvention>();

public override bool CanHandle(ITypeSystemObjectContext context) => true;

Expand Down Expand Up @@ -48,19 +48,22 @@ public class FilterTypeInterceptor
field.Type = field.Type.With(scope: discoveryContext.Scope);
}

if (convention.TryGetHandler(
discoveryContext,
def,
filterFieldDefinition,
out IFilterFieldHandler? handler))
if (filterFieldDefinition.Handler is null)
{
filterFieldDefinition.Handler = handler;
}
else
{
throw ThrowHelper.FilterInterceptor_NoHandlerFoundForField(
if (convention.TryGetHandler(
discoveryContext,
def,
filterFieldDefinition);
filterFieldDefinition,
out IFilterFieldHandler? handler))
{
filterFieldDefinition.Handler = handler;
}
else
{
throw ThrowHelper.FilterInterceptor_NoHandlerFoundForField(
def,
filterFieldDefinition);
}
}
}
}
Expand Down Expand Up @@ -92,6 +95,7 @@ public class FilterTypeInterceptor
convention = context.GetFilterConvention(scope);
_conventions[scope ?? ""] = convention;
}

return convention;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ public class FilterFieldDefinition
public string? Scope { get; set; }
}
}

Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using HotChocolate.Configuration;
using HotChocolate.Data.Filters;
using HotChocolate.Data.Filters.Expressions;
using HotChocolate.Language;
using HotChocolate.Types;
using Snapshooter.Xunit;
Expand Down Expand Up @@ -293,6 +295,45 @@ public void FilterInputType_Should_UseCustomFilterType_When_Nested()
builder.Create().Print().MatchSnapshot();
}

[Fact]
public void FilterInputType_Should_NotOverrideHandler_OnBeforeCreate()
{
// arrange
ISchema builder = SchemaBuilder.New()
.AddFiltering()
.AddQueryType<CustomHandlerQueryType >()
.Create();

// act
builder.TryGetType<CustomHandlerFilterInputType>(
"TestName",
out CustomHandlerFilterInputType? type);

// assert
Assert.NotNull(type);
Assert.IsType<CustomHandler>(Assert.IsType<FilterField>(type.Fields["id"]).Handler);
}

[Fact]
public void FilterInputType_Should_NotOverrideHandler_OnBeforeCompletion()
{
// arrange
ISchema builder = SchemaBuilder.New()
.AddFiltering()
.AddQueryType<CustomHandlerQueryType >()
.Create();

// act
builder.TryGetType<CustomHandlerFilterInputType>(
"TestName",
out CustomHandlerFilterInputType? type);

// assert
Assert.NotNull(type);
Assert.IsType<CustomHandler>(Assert.IsType<FilterField>(type.Fields["friends"]).Handler);
Assert.IsType<QueryableDefaultFieldHandler>(Assert.IsType<FilterField>(type.Fields["name"]).Handler);
}

public class FooDirectiveType
: DirectiveType<FooDirective>
{
Expand Down Expand Up @@ -378,5 +419,43 @@ protected override void Configure(IObjectTypeDescriptor<User> descriptor)
.UseFiltering<UserFilterInputType>();
}
}

public class CustomHandlerFilterInputType : FilterInputType<User>
{
protected override void Configure(IFilterInputTypeDescriptor<User> descriptor)
{
descriptor.Name("TestName");
descriptor.Field(x => x.Id)
.Extend()
.OnBeforeCreate(x => x.Handler = new CustomHandler());

descriptor.Field(x => x.Friends)
.Extend()
.OnBeforeCompletion((ctx, x) => x.Handler = new CustomHandler());
}
}

public class CustomHandlerQueryType : ObjectType<User>
{
protected override void Configure(IObjectTypeDescriptor<User> descriptor)
{
descriptor.Name(nameof(Query));
descriptor
.Field("foo")
.Resolve(new List<User>())
.UseFiltering<CustomHandlerFilterInputType>();
}
}

public class CustomHandler : IFilterFieldHandler
{
public bool CanHandle(
ITypeDiscoveryContext context,
IFilterInputTypeDefinition typeDefinition,
IFilterFieldDefinition fieldDefinition)
{
throw new NotImplementedException();
}
}
}
}