Skip to content

Commit

Permalink
Fixed [ID] on input mutation conventions (#4507)
Browse files Browse the repository at this point in the history
  • Loading branch information
PascalSenn authored Nov 30, 2021
1 parent 0d4622a commit b08b1e0
Show file tree
Hide file tree
Showing 10 changed files with 110 additions and 33 deletions.
30 changes: 15 additions & 15 deletions src/HotChocolate/Core/HotChocolate.Core.sln
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HotChocolate.Types.NodaTime
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HotChocolate.AspNetCore", "..\AspNetCore\src\AspNetCore\HotChocolate.AspNetCore.csproj", "{4AD904D1-7727-48EF-88D9-7B38D98EB314}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Types.Mutations", "src\Types.Mutations\Types.Mutations.csproj", "{F3621170-A3D6-4BE7-9E16-E32BA9ABA1DB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HotChocolate.Types.Mutations", "src\Types.Mutations\HotChocolate.Types.Mutations.csproj", "{2B7E7416-E093-4763-B839-504CBFBC8F1C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HotChocolate.Types.Mutations.Tests", "test\Types.Mutations.Tests\HotChocolate.Types.Mutations.Tests.csproj", "{F6FFA925-8C49-4594-9FF2-8F571C2D6389}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HotChocolate.Types", "src\Types\HotChocolate.Types.csproj", "{08A8915E-CFB2-46F6-9D24-CCB28BDA1446}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -603,18 +603,6 @@ Global
{4AD904D1-7727-48EF-88D9-7B38D98EB314}.Release|x64.Build.0 = Release|Any CPU
{4AD904D1-7727-48EF-88D9-7B38D98EB314}.Release|x86.ActiveCfg = Release|Any CPU
{4AD904D1-7727-48EF-88D9-7B38D98EB314}.Release|x86.Build.0 = Release|Any CPU
{F3621170-A3D6-4BE7-9E16-E32BA9ABA1DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F3621170-A3D6-4BE7-9E16-E32BA9ABA1DB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F3621170-A3D6-4BE7-9E16-E32BA9ABA1DB}.Debug|x64.ActiveCfg = Debug|Any CPU
{F3621170-A3D6-4BE7-9E16-E32BA9ABA1DB}.Debug|x64.Build.0 = Debug|Any CPU
{F3621170-A3D6-4BE7-9E16-E32BA9ABA1DB}.Debug|x86.ActiveCfg = Debug|Any CPU
{F3621170-A3D6-4BE7-9E16-E32BA9ABA1DB}.Debug|x86.Build.0 = Debug|Any CPU
{F3621170-A3D6-4BE7-9E16-E32BA9ABA1DB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F3621170-A3D6-4BE7-9E16-E32BA9ABA1DB}.Release|Any CPU.Build.0 = Release|Any CPU
{F3621170-A3D6-4BE7-9E16-E32BA9ABA1DB}.Release|x64.ActiveCfg = Release|Any CPU
{F3621170-A3D6-4BE7-9E16-E32BA9ABA1DB}.Release|x64.Build.0 = Release|Any CPU
{F3621170-A3D6-4BE7-9E16-E32BA9ABA1DB}.Release|x86.ActiveCfg = Release|Any CPU
{F3621170-A3D6-4BE7-9E16-E32BA9ABA1DB}.Release|x86.Build.0 = Release|Any CPU
{2B7E7416-E093-4763-B839-504CBFBC8F1C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2B7E7416-E093-4763-B839-504CBFBC8F1C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2B7E7416-E093-4763-B839-504CBFBC8F1C}.Debug|x64.ActiveCfg = Debug|Any CPU
Expand All @@ -639,6 +627,18 @@ Global
{F6FFA925-8C49-4594-9FF2-8F571C2D6389}.Release|x64.Build.0 = Release|Any CPU
{F6FFA925-8C49-4594-9FF2-8F571C2D6389}.Release|x86.ActiveCfg = Release|Any CPU
{F6FFA925-8C49-4594-9FF2-8F571C2D6389}.Release|x86.Build.0 = Release|Any CPU
{08A8915E-CFB2-46F6-9D24-CCB28BDA1446}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{08A8915E-CFB2-46F6-9D24-CCB28BDA1446}.Debug|Any CPU.Build.0 = Debug|Any CPU
{08A8915E-CFB2-46F6-9D24-CCB28BDA1446}.Debug|x64.ActiveCfg = Debug|Any CPU
{08A8915E-CFB2-46F6-9D24-CCB28BDA1446}.Debug|x64.Build.0 = Debug|Any CPU
{08A8915E-CFB2-46F6-9D24-CCB28BDA1446}.Debug|x86.ActiveCfg = Debug|Any CPU
{08A8915E-CFB2-46F6-9D24-CCB28BDA1446}.Debug|x86.Build.0 = Debug|Any CPU
{08A8915E-CFB2-46F6-9D24-CCB28BDA1446}.Release|Any CPU.ActiveCfg = Release|Any CPU
{08A8915E-CFB2-46F6-9D24-CCB28BDA1446}.Release|Any CPU.Build.0 = Release|Any CPU
{08A8915E-CFB2-46F6-9D24-CCB28BDA1446}.Release|x64.ActiveCfg = Release|Any CPU
{08A8915E-CFB2-46F6-9D24-CCB28BDA1446}.Release|x64.Build.0 = Release|Any CPU
{08A8915E-CFB2-46F6-9D24-CCB28BDA1446}.Release|x86.ActiveCfg = Release|Any CPU
{08A8915E-CFB2-46F6-9D24-CCB28BDA1446}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -685,9 +685,9 @@ Global
{07F3E312-EC4C-4B71-A095-E478DF4CB52B} = {37B9D3B1-CA34-4720-9A0B-CFF1E64F52C2}
{414B6DBE-1A3A-42DC-9116-3F9A433C6BBB} = {7462D089-D350-44D6-8131-896D949A65B7}
{4AD904D1-7727-48EF-88D9-7B38D98EB314} = {7637D30E-7339-4D4E-9424-87CF2394D234}
{F3621170-A3D6-4BE7-9E16-E32BA9ABA1DB} = {37B9D3B1-CA34-4720-9A0B-CFF1E64F52C2}
{2B7E7416-E093-4763-B839-504CBFBC8F1C} = {37B9D3B1-CA34-4720-9A0B-CFF1E64F52C2}
{F6FFA925-8C49-4594-9FF2-8F571C2D6389} = {7462D089-D350-44D6-8131-896D949A65B7}
{08A8915E-CFB2-46F6-9D24-CCB28BDA1446} = {37B9D3B1-CA34-4720-9A0B-CFF1E64F52C2}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E4D94C77-6657-4630-9D42-0A9AC5153A1B}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Linq;
using HotChocolate.Configuration;
using HotChocolate.Types.Descriptors;
using HotChocolate.Types.Descriptors.Definitions;
Expand Down Expand Up @@ -132,13 +133,14 @@ private static void MergeFieldWithArgument(
definition.DefaultValue = argumentDefinition.DefaultValue;
definition.Ignore = argumentDefinition.Ignore;
definition.RuntimeDefaultValue = argumentDefinition.RuntimeDefaultValue;

definition.RuntimeType = argumentDefinition.Parameter.ParameterType;
definition.ContextData.AddRange(argumentDefinition.ContextData);
definition.Formatters.AddRange(argumentDefinition.Formatters);

if (argumentDefinition.HasConfigurations)
{
definition.Configurations.AddRange(argumentDefinition.Configurations);
definition.Configurations.AddRange(
argumentDefinition.Configurations.Select(x => x.Copy(definition)));
}

if (argumentDefinition.HasDependencies)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,27 +46,32 @@ public Expression Build(ParameterInfo parameter, Expression context)
throw new ArgumentException("Could not find the InputAttribute", nameof(parameter));
}

Expression argumentValue =
Call(context,
_getArgumentValue,
Convert(Constant(attribute.ArgumentName), typeof(NameString)));
ParameterExpression variable =
Variable(typeof(Dictionary<string, object>), "val");

Expression expr =
return Block(new[]
{
variable
},
Assign(
variable,
Call(context,
_getArgumentValue,
Convert(Constant(attribute.ArgumentName), typeof(NameString)))),
Condition(
And(
NotEqual(argumentValue, _null),
NotEqual(variable, _null),
Call(
argumentValue,
variable,
_containsKey,
Constant(parameter.Name!))),
// if
Convert(
Property(argumentValue, _getValue, Constant(parameter.Name)),
Property(variable, _getValue, Constant(parameter.Name)),
parameter.ParameterType),
// else
Convert(_null, parameter.ParameterType));

return expr;
Convert(_null, parameter.ParameterType))
);
}
}
}
4 changes: 2 additions & 2 deletions src/HotChocolate/Core/src/Types/Types/Argument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,9 @@ protected override void OnCompleteField(
}

base.OnCompleteField(context, declaringMember, definition);
;

Type = context.GetType<IInputType>(definition.Type!);
_runtimeType = definition.Parameter?.ParameterType!;
_runtimeType = definition.RuntimeType ?? definition.Parameter?.ParameterType!;
_runtimeType = CompleteRuntimeType(Type, _runtimeType, out var isOptional);
DefaultValue = CompleteDefaultValue(context, definition, Type, Coordinate);
IsOptional = isOptional;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ public ArgumentDefinition(

public ParameterInfo? Parameter { get; set; }

public Type? RuntimeType { get; set; }

public IList<IInputValueFormatter> Formatters =>
_formatters ??= new List<IInputValueFormatter>();

Expand Down
2 changes: 1 addition & 1 deletion src/HotChocolate/Core/src/Types/Types/InputField.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ protected override void OnCompleteField(
base.OnCompleteField(context, declaringMember, definition);

Type = context.GetType<IInputType>(definition.Type!);
_runtimeType = definition.Property?.PropertyType!;
_runtimeType = definition.RuntimeType ?? definition.Property?.PropertyType!;
_runtimeType = CompleteRuntimeType(Type, _runtimeType, out var isOptional);
DefaultValue = CompleteDefaultValue(context, definition, Type, Coordinate);
IsOptional = isOptional;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,13 @@ private static void AddSerializerToInputField(
ITypeInspector typeInspector = completionContext.TypeInspector;
IExtendedType? resultType;

if (definition is InputFieldDefinition inputField)
if (definition is InputFieldDefinition { RuntimeType: { } runtimeType })
{
resultType = typeInspector.GetReturnType(inputField.Property!, true);
resultType = typeInspector.GetType(runtimeType);
}
else if (definition is InputFieldDefinition { Property: not null } inputField)
{
resultType = typeInspector.GetReturnType(inputField.Property, true);
}
else if (definition.Parameter is not null)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using HotChocolate.Execution;
using HotChocolate.Types.Relay;
using Microsoft.Extensions.DependencyInjection;
using Snapshooter;
using Snapshooter.Xunit;
Expand Down Expand Up @@ -261,6 +264,38 @@ public async Task InputArgumentMiddleware_Should_DefineTypeNames_When_MultipleIn
executor.Schema.Print().MatchSnapshot(snapshotName);
}

[Fact]
public async Task InputArgumentMiddleware_Should_MergeFormatter_When_UsedWithId()
{
// Arrange
IRequestExecutor executor =
await new ServiceCollection()
.AddGraphQL()
.AddQueryType<QueryId>()
.EnableMutationConvention()
.BuildRequestExecutorAsync();

// Act
string id = new IdSerializer()
.Serialize("Item", Guid.Parse("5ea909ec-ae00-4d00-8f96-afe0e8bdcad2"));

IExecutionResult res = await executor
.ExecuteAsync(@"
query Foo($id: ID!){
createFoo(input: {
bar: $id
})
}
",
new Dictionary<string, object?>() { ["id"] = id });

// Assert
res.ToJson().MatchSnapshot();
SnapshotFullName fullName = Snapshot.FullName();
SnapshotFullName snapshotName = new(fullName.Filename + "_schema", fullName.FolderPath);
executor.Schema.Print().MatchSnapshot(snapshotName);
}

[Fact]
public async Task InputArgumentMiddleware_Should_Throw_WhenTypeNamesCollide()
{
Expand Down Expand Up @@ -369,4 +404,11 @@ public Foo CreateFoo(
[Input(TypeName = "SecondOne")] string baz) =>
new(bar + baz);
}

public class QueryId
{
[ID("Item")]
[Input]
public Guid CreateFoo([ID("Item")] Guid bar) => bar;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"data": {
"createFoo": "SXRlbQpnNWVhOTA5ZWNhZTAwNGQwMDhmOTZhZmUwZThiZGNhZDI="
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
schema {
query: QueryId
}

type QueryId {
createFoo(input: CreateFooInput): ID!
}

input CreateFooInput {
bar: ID!
}

"The `@defer` directive may be provided for fragment spreads and inline fragments to inform the executor to delay the execution of the current fragment to indicate deprioritization of the current fragment. A query with `@defer` directive will cause the request to potentially return multiple responses, where non-deferred data is delivered in the initial response and data deferred is delivered in a subsequent response. `@include` and `@skip` take precedence over `@defer`."
directive @defer("If this argument label has a value other than null, it will be passed on to the result of this defer directive. This label is intended to give client applications a way to identify to which fragment a deferred result belongs to." label: String "Deferred when true." if: Boolean) on FRAGMENT_SPREAD | INLINE_FRAGMENT

"The `@stream` directive may be provided for a field of `List` type so that the backend can leverage technology such as asynchronous iterators to provide a partial list in the initial response, and additional list items in subsequent responses. `@include` and `@skip` take precedence over `@stream`."
directive @stream("If this argument label has a value other than null, it will be passed on to the result of this stream directive. This label is intended to give client applications a way to identify to which fragment a streamed result belongs to." label: String "The initial elements that shall be send down to the consumer." initialCount: Int! = 0 "Streamed when true." if: Boolean) on FIELD

0 comments on commit b08b1e0

Please sign in to comment.