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

Fixed [ID] on input mutation conventions #4507

Merged
merged 3 commits into from
Nov 30, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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