graphql-dotnet / conventions

GraphQL Conventions Library for .NET
MIT License
233 stars 63 forks source link

Error when getting enum value => Argument 'input' has invalid value #240

Open Benkhouds opened 1 year ago

Benkhouds commented 1 year ago

I'm using the conventions library as a mock server, and I couldn't figure out how to map values, here's a query example ` test(input: { accountName: "Compte principal" name: "test" companyType: Association // this is an enum as you can see not a string value businessActivity: AdministrativeServices // same monthlyPaymentVolume: Between10000And50000 // same email: "test@test.com" language: "FR"

}) {
... onSuccessPayload {
  __typename
   status
}
... on BadRequestRejection {
  __typename
  message
}
... on ValidationRejection {
  __typename
  message
}
... on ForbiddenRejection {
  __typename
  message
}

} } `

And i'm using a I'm only using a requestHandler, so when i get a request I pass it to requestHandler.ProcessRequestAsync. I have a workaround to pass the enum as string value and then parse it, but i'd rather not. here's the full error I got: In field 'businessActivity': [Expected type 'BusinessActivity', found AdministrativeServices.] In field 'monthlyPaymentVolume': [Expected type 'MonthlyPaymentVolume', found Between10000And50000.]\",\"locations\":[{\"line\":2,\"column\":31}],\"extensions\":{\"code\":\"FIELD_RESOLUTION\",\"codes\":[\"FIELD_RESOLUTION\",\"ARGUMENTS_OF_CORRECT_TYPE_ERROR\"]}}]

Benkhouds commented 1 year ago

I think i found the issue but still don't know how to fix it. When i describe my schema here's the screenshot for my enum image

As you can see it changed it to constant case, but my enum is PascalCase

tlil commented 1 year ago

I think i found the issue but still don't know how to fix it. When i describe my schema here's the screenshot for my enum

image

As you can see it changed it to constant case, but my enum is PascalCase

This is by design as enum values are all caps by convention following the recommendations in the GraphQL spec:

https://spec.graphql.org/June2018/#sec-Enum-Value

image

Benkhouds commented 1 year ago

I'm not saying that this is not the convention, But for my case, the enums are already there (i'm mocking a real third party graphql server) and they are PascalCase. It would be really great if you can provide me with a solution to convert the values to PascalCase, i'm out of ideas :( Thanks

tlil commented 1 year ago

I'm not saying that this is not the convention, But for my case, the enums are already there (i'm mocking a real third party graphql server) and they are PascalCase. It would be really great if you can provide me with a solution to convert the values to PascalCase, i'm out of ideas :( Thanks

You can use the [Name(...)] attribute on each enum value:

CleanShot 2022-12-18 at 19 38 52

See the Enum_Members_Have_Correct_Names unit test (above, with the last value as an addition) :-)

Benkhouds commented 1 year ago

hoped for a more generic solution to apply for all enums but this will do. Thanks a lot

tlil commented 1 year ago

hoped for a more generic solution to apply for all enums but this will do. Thanks a lot

See answer in #241 – adding your own attribute implementing MetaDataAttributeBase and IDefaultAttribute gives you a generic solution

Benkhouds commented 1 year ago

So, after trying what you said previously, nothing really worked but i closed the issue because i went with sending the enum as a string and parsing it later (which i really don't like). And now, since I'm back working at this, I tried creating a class implementing the both MetaDataAttributeBase and IDefaultAttribute, to override MapEnumMember, but it seems that it's executed before the MapEnumMember of the NameAttribute. if the NameAttribute class had virtual methods I could override its implementation but that's not the case. Is it a choice you made that only Constant Case enums are supported unless specifying explicitly on each enum member (which is a pain to be honest since we have hundreds of enums). I propose 3 simple solutions : 1) Adding EnumCase as a configuration and updating the MapEnumMember to behave accordingly 2) making the NameNormalizer field public, so it can be replaced 3) inside DiscoverDefaultAttributes, if there's a default attribute that's inheriting from one of the types inside _defaultAttributes, remove parent from list If you agree on any of the above, I can make a pr to do the change