Skip to content

Commit

Permalink
Fixed Middleware Issues (#782)
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelstaib authored May 23, 2019
1 parent e81aa18 commit 04e7d1a
Show file tree
Hide file tree
Showing 48 changed files with 1,007 additions and 291 deletions.
4 changes: 2 additions & 2 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
}
},
{
"label": "build benchmarks",
"command": "dotnet build benchmarks /property:GenerateFullPaths=true",
"label": "build server",
"command": "dotnet build src/Server /property:GenerateFullPaths=true",
"type": "shell",
"presentation": {
"reveal": "silent"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"Errors": [
{
"Message": "Cannot return null for non-nullable field.",
"Code": null,
"Code": "EXEC_NON_NULL_VIOLATION",
"Path": [
"foo",
"nonnull_list_nonnull_element",
Expand All @@ -20,7 +20,9 @@
}
],
"Exception": null,
"Extensions": {}
"Extensions": {
"code": "EXEC_NON_NULL_VIOLATION"
}
}
],
"ContextData": {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"Errors": [
{
"Message": "Cannot return null for non-nullable field.",
"Code": null,
"Code": "EXEC_NON_NULL_VIOLATION",
"Path": [
"foo",
"nonnull_list_nullable_element",
Expand All @@ -24,7 +24,9 @@
}
],
"Exception": null,
"Extensions": {}
"Extensions": {
"code": "EXEC_NON_NULL_VIOLATION"
}
}
],
"ContextData": {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"Errors": [
{
"Message": "Cannot return null for non-nullable field.",
"Code": null,
"Code": "EXEC_NON_NULL_VIOLATION",
"Path": [
"foo",
"nullable_list_nonnull_element",
Expand All @@ -22,7 +22,9 @@
}
],
"Exception": null,
"Extensions": {}
"Extensions": {
"code": "EXEC_NON_NULL_VIOLATION"
}
}
],
"ContextData": {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"Errors": [
{
"Message": "Cannot return null for non-nullable field.",
"Code": null,
"Code": "EXEC_NON_NULL_VIOLATION",
"Path": [
"foo",
"nullable_list_nullable_element",
Expand All @@ -24,7 +24,9 @@
}
],
"Exception": null,
"Extensions": {}
"Extensions": {
"code": "EXEC_NON_NULL_VIOLATION"
}
}
],
"ContextData": {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"Errors": [
{
"Message": "Cannot return null for non-nullable field.",
"Code": null,
"Code": "EXEC_NON_NULL_VIOLATION",
"Path": [
"foo",
"nonnull_prop",
Expand All @@ -19,7 +19,9 @@
}
],
"Exception": null,
"Extensions": {}
"Extensions": {
"code": "EXEC_NON_NULL_VIOLATION"
}
}
],
"ContextData": {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"Errors": [
{
"Message": "Cannot return null for non-nullable field.",
"Code": null,
"Code": "EXEC_NON_NULL_VIOLATION",
"Path": [
"foo",
"nullable_prop",
Expand All @@ -21,7 +21,9 @@
}
],
"Exception": null,
"Extensions": {}
"Extensions": {
"code": "EXEC_NON_NULL_VIOLATION"
}
}
],
"ContextData": {}
Expand Down
7 changes: 7 additions & 0 deletions src/Core/Core/Execution/ExecErrorCodes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace HotChocolate.Execution
{
internal static class ExecErrorCodes
{
public const string NonNullViolation = "EXEC_NON_NULL_VIOLATION";
}
}
1 change: 1 addition & 0 deletions src/Core/Core/Execution/ExecutionContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public ExecutionContext(
requestContext.ServiceScope.ServiceProvider);
}


public ISchema Schema { get; }

public IRequestServiceScope ServiceScope =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,6 @@ private static FieldDelegate BuildComponent(

for (int i = components.Count - 1; i >= 0; i--)
{

DirectiveDelegate component = components[i].Invoke(next);

next = context =>
Expand Down
6 changes: 4 additions & 2 deletions src/Core/Core/Execution/Utilities/ValueCompletion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,10 @@ private static void HandleNonNullViolation(
{
if (!context.HasErrors)
{
context.AddError(b => b.SetMessage(
CoreResources.HandleNonNullViolation_Message));
context.AddError(b => b
.SetMessage(CoreResources
.HandleNonNullViolation_Message)
.SetCode(ExecErrorCodes.NonNullViolation));
}

context.IsViolatingNonNullType = true;
Expand Down
202 changes: 202 additions & 0 deletions src/Core/Types.Tests/Types/DirectiveTypeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using HotChocolate.Language;
using HotChocolate.Resolvers;
using HotChocolate.Types.Descriptors;
using Snapshooter.Xunit;
using Xunit;
Expand Down Expand Up @@ -279,6 +280,194 @@ public void Ignore_Argument2_Property()
schema.ToString().MatchSnapshot();
}

[Fact]
public void Use_DelegateMiddleware()
{
// arrange
// act
ISchema schema = SchemaBuilder.New()
.AddQueryType(c => c
.Name("Query")
.Directive("foo")
.Field("foo")
.Type<StringType>()
.Resolver("bar"))
.AddDirectiveType(new DirectiveType<CustomDirective2>(d => d
.Name("foo")
.Location(DirectiveLocation.Object)
.Use(next => context => Task.CompletedTask)))
.Create();

// assert
DirectiveType directive = schema.GetDirectiveType("foo");
Assert.Collection(directive.MiddlewareComponents,
t => Assert.NotNull(t));
}

[Fact]
public void Use_ClassMiddleware()
{
// arrange
// act
ISchema schema = SchemaBuilder.New()
.AddQueryType(c => c
.Name("Query")
.Directive("foo")
.Field("foo")
.Type<StringType>()
.Resolver("bar"))
.AddDirectiveType(new DirectiveType<CustomDirective2>(d => d
.Name("foo")
.Location(DirectiveLocation.Object)
.Use<DirectiveMiddleware>()))
.Create();

// assert
DirectiveType directive = schema.GetDirectiveType("foo");
Assert.Collection(directive.MiddlewareComponents,
t => Assert.NotNull(t));
}

[Fact]
public void Use_ClassMiddleware_WithFactory()
{
// arrange
// act
ISchema schema = SchemaBuilder.New()
.AddQueryType(c => c
.Name("Query")
.Directive("foo")
.Field("foo")
.Type<StringType>()
.Resolver("bar"))
.AddDirectiveType(new DirectiveType<CustomDirective2>(d => d
.Name("foo")
.Location(DirectiveLocation.Object)
.Use((sp, next) => new DirectiveMiddleware(next))))
.Create();

// assert
DirectiveType directive = schema.GetDirectiveType("foo");
Assert.Collection(directive.MiddlewareComponents,
t => Assert.NotNull(t));
}

[Fact]
public void Use_ClassMiddleware_WithFactoryNull_ArgumentNullException()
{
// arrange
// act
Action action = () => SchemaBuilder.New()
.AddQueryType(c => c
.Name("Query")
.Directive("foo")
.Field("foo")
.Type<StringType>()
.Resolver("bar"))
.AddDirectiveType(new DirectiveType<CustomDirective2>(d => d
.Name("foo")
.Location(DirectiveLocation.Object)
.Use(null)))
.Create();

// assert
Assert.Throws<SchemaException>(action);
}

[Fact]
public void Use2_DelegateMiddleware()
{
// arrange
// act
ISchema schema = SchemaBuilder.New()
.AddQueryType(c => c
.Name("Query")
.Directive("foo")
.Field("foo")
.Type<StringType>()
.Resolver("bar"))
.AddDirectiveType(new DirectiveType(d => d
.Name("foo")
.Location(DirectiveLocation.Object)
.Use(next => context => Task.CompletedTask)))
.Create();

// assert
DirectiveType directive = schema.GetDirectiveType("foo");
Assert.Collection(directive.MiddlewareComponents,
t => Assert.NotNull(t));
}

[Fact]
public void Use2_ClassMiddleware()
{
// arrange
// act
ISchema schema = SchemaBuilder.New()
.AddQueryType(c => c
.Name("Query")
.Directive("foo")
.Field("foo")
.Type<StringType>()
.Resolver("bar"))
.AddDirectiveType(new DirectiveType(d => d
.Name("foo")
.Location(DirectiveLocation.Object)
.Use<DirectiveMiddleware>()))
.Create();

// assert
DirectiveType directive = schema.GetDirectiveType("foo");
Assert.Collection(directive.MiddlewareComponents,
t => Assert.NotNull(t));
}

[Fact]
public void Use2_ClassMiddleware_WithFactory()
{
// arrange
// act
ISchema schema = SchemaBuilder.New()
.AddQueryType(c => c
.Name("Query")
.Directive("foo")
.Field("foo")
.Type<StringType>()
.Resolver("bar"))
.AddDirectiveType(new DirectiveType(d => d
.Name("foo")
.Location(DirectiveLocation.Object)
.Use((sp, next) => new DirectiveMiddleware(next))))
.Create();

// assert
DirectiveType directive = schema.GetDirectiveType("foo");
Assert.Collection(directive.MiddlewareComponents,
t => Assert.NotNull(t));
}

[Fact]
public void Use2_ClassMiddleware_WithFactoryNull_ArgumentNullException()
{
// arrange
// act
Action action = () => SchemaBuilder.New()
.AddQueryType(c => c
.Name("Query")
.Directive("foo")
.Field("foo")
.Type<StringType>()
.Resolver("bar"))
.AddDirectiveType(new DirectiveType(d => d
.Name("foo")
.Location(DirectiveLocation.Object)
.Use(null)))
.Create();

// assert
Assert.Throws<SchemaException>(action);
}

public class CustomDirectiveType
: DirectiveType<CustomDirective>
{
Expand All @@ -292,6 +481,19 @@ protected override void Configure(
}
}

public class DirectiveMiddleware
{
private FieldDelegate _next;

public DirectiveMiddleware(FieldDelegate next)
{
_next = next;
}

public Task InvokeAsync(IDirectiveContext context) =>
Task.CompletedTask;
}

public class CustomDirective
{
public string Argument { get; set; }
Expand Down
2 changes: 1 addition & 1 deletion src/Core/Types/Resolvers/ClassMiddlewareFactory.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Linq;
using System.Reflection;
using HotChocolate.Utilities;
Expand Down
Loading

0 comments on commit 04e7d1a

Please sign in to comment.