Repository: apollographql/apollo-rs (rust)

Issue:
Enum values provided to scalars
Validation does not currently accept something like this:

```graphql
scalar Currency
type Query {
  convertToUSD(amount: Int!, currency: Currency!): Int!
}

query {
  convertToUSD(amount: 100, currency: EUR)
}
```

which is accepted by graphql-js and (rarely) used by customers. I don't love it, but we already accept enum values nested inside lists or objects as input for custom scalars, so it makes sense to accept this too.

Pull request:
fix(compiler): accept enum value (unquoted string) as input for custom scalars
Validation does not currently accept something like this:

```graphql
scalar Currency
type Query {
  convertToUSD(amount: Int!, currency: Currency!): Int!
}

query {
  convertToUSD(amount: 100, currency: EUR)
}
```

which is accepted by graphql-js and (rarely) used by customers. I don't love it, but we already accept enum values nested inside lists or objects as input for custom scalars, so it makes sense to accept this too.

Fixes #834

Patch:
diff --git a/crates/apollo-compiler/src/validation/value.rs b/crates/apollo-compiler/src/validation/value.rs
index 04720fe..3fdfb90 100644
--- a/crates/apollo-compiler/src/validation/value.rs
+++ b/crates/apollo-compiler/src/validation/value.rs
@@ -159,6 +159,9 @@ pub(crate) fn value_of_correct_type(
             _ => diagnostics.push(unsupported_type(arg_value, ty)),
         },
         ast::Value::Enum(value) => match &type_definition {
+            schema::ExtendedType::Scalar(scalar) if !scalar.is_built_in() => {
+                // Accept enum values as input for custom scalars
+            }
             schema::ExtendedType::Enum(enum_) => {
                 if !enum_.values.contains_key(value) {
                     diagnostics.push(ValidationError::new(
@@ -199,7 +202,7 @@ pub(crate) fn value_of_correct_type(
             }
         }
         ast::Value::Object(obj) => match &type_definition {
-            schema::ExtendedType::Scalar(scalar) if !scalar.is_built_in() => (),
+            schema::ExtendedType::Scalar(scalar) if !scalar.is_built_in() => {}
             schema::ExtendedType::InputObject(input_obj) => {
                 let undefined_field = obj
                     .iter()


Test patch:
diff --git a/crates/apollo-compiler/test_data/ok/0041_unquoted_string_for_custom_scalar.graphql b/crates/apollo-compiler/test_data/ok/0041_unquoted_string_for_custom_scalar.graphql
new file mode 100644
index 0000000..912b08a
--- /dev/null
+++ b/crates/apollo-compiler/test_data/ok/0041_unquoted_string_for_custom_scalar.graphql
@@ -0,0 +1,9 @@
+scalar Currency
+
+type Query {
+  convertToUSD(amount: Int!, currency: Currency!): Int!
+}
+
+query {
+  convertToUSD(amount: 100, currency: EUR)
+}
diff --git a/crates/apollo-compiler/test_data/ok/0041_unquoted_string_for_custom_scalar.txt b/crates/apollo-compiler/test_data/ok/0041_unquoted_string_for_custom_scalar.txt
new file mode 100644
index 0000000..ef94a61
--- /dev/null
+++ b/crates/apollo-compiler/test_data/ok/0041_unquoted_string_for_custom_scalar.txt
@@ -0,0 +1,173 @@
+Schema {
+    sources: {
+        -1: SourceFile {
+            path: "built_in.graphql",
+            source_text: include_str!("built_in.graphql"),
+        },
+        40: SourceFile {
+            path: "0041_unquoted_string_for_custom_scalar.graphql",
+            source_text: "scalar Currency\n\ntype Query {\n  convertToUSD(amount: Int!, currency: Currency!): Int!\n}\n\nquery {\n  convertToUSD(amount: 100, currency: EUR)\n}\n",
+        },
+    },
+    schema_definition: SchemaDefinition {
+        description: None,
+        directives: [],
+        query: Some(
+            ComponentName {
+                origin: Definition,
+                name: "Query",
+            },
+        ),
+        mutation: None,
+        subscription: None,
+    },
+    directive_definitions: {
+        "skip": built_in_directive!("skip"),
+        "include": built_in_directive!("include"),
+        "deprecated": built_in_directive!("deprecated"),
+        "specifiedBy": built_in_directive!("specifiedBy"),
+    },
+    types: {
+        "__Schema": built_in_type!("__Schema"),
+        "__Type": built_in_type!("__Type"),
+        "__TypeKind": built_in_type!("__TypeKind"),
+        "__Field": built_in_type!("__Field"),
+        "__InputValue": built_in_type!("__InputValue"),
+        "__EnumValue": built_in_type!("__EnumValue"),
+        "__Directive": built_in_type!("__Directive"),
+        "__DirectiveLocation": built_in_type!("__DirectiveLocation"),
+        "Int": built_in_type!("Int"),
+        "Float": built_in_type!("Float"),
+        "String": built_in_type!("String"),
+        "Boolean": built_in_type!("Boolean"),
+        "ID": built_in_type!("ID"),
+        "Currency": Scalar(
+            0..15 @40 ScalarType {
+                description: None,
+                name: "Currency",
+                directives: [],
+            },
+        ),
+        "Query": Object(
+            17..87 @40 ObjectType {
+                description: None,
+                name: "Query",
+                implements_interfaces: {},
+                directives: [],
+                fields: {
+                    "convertToUSD": Component {
+                        origin: Definition,
+                        node: 32..85 @40 FieldDefinition {
+                            description: None,
+                            name: "convertToUSD",
+                            arguments: [
+                                45..57 @40 InputValueDefinition {
+                                    description: None,
+                                    name: "amount",
+                                    ty: 53..57 @40 NonNullNamed(
+                                        "Int",
+                                    ),
+                                    default_value: None,
+                                    directives: [],
+                                },
+                                59..78 @40 InputValueDefinition {
+                                    description: None,
+                                    name: "currency",
+                                    ty: 69..78 @40 NonNullNamed(
+                                        "Currency",
+                                    ),
+                                    default_value: None,
+                                    directives: [],
+                                },
+                            ],
+                            ty: NonNullNamed(
+                                "Int",
+                            ),
+                            directives: [],
+                        },
+                    },
+                },
+            },
+        ),
+    },
+}
+ExecutableDocument {
+    sources: {
+        -1: SourceFile {
+            path: "built_in.graphql",
+            source_text: include_str!("built_in.graphql"),
+        },
+        40: SourceFile {
+            path: "0041_unquoted_string_for_custom_scalar.graphql",
+            source_text: "scalar Currency\n\ntype Query {\n  convertToUSD(amount: Int!, currency: Currency!): Int!\n}\n\nquery {\n  convertToUSD(amount: 100, currency: EUR)\n}\n",
+        },
+    },
+    anonymous_operation: Some(
+        89..141 @40 Operation {
+            operation_type: Query,
+            name: None,
+            variables: [],
+            directives: [],
+            selection_set: SelectionSet {
+                ty: "Query",
+                selections: [
+                    Field(
+                        99..139 @40 Field {
+                            definition: 32..85 @40 FieldDefinition {
+                                description: None,
+                                name: "convertToUSD",
+                                arguments: [
+                                    45..57 @40 InputValueDefinition {
+                                        description: None,
+                                        name: "amount",
+                                        ty: 53..57 @40 NonNullNamed(
+                                            "Int",
+                                        ),
+                                        default_value: None,
+                                        directives: [],
+                                    },
+                                    59..78 @40 InputValueDefinition {
+                                        description: None,
+                                        name: "currency",
+                                        ty: 69..78 @40 NonNullNamed(
+                                            "Currency",
+                                        ),
+                                        default_value: None,
+                                        directives: [],
+                                    },
+                                ],
+                                ty: NonNullNamed(
+                                    "Int",
+                                ),
+                                directives: [],
+                            },
+                            alias: None,
+                            name: "convertToUSD",
+                            arguments: [
+                                112..123 @40 Argument {
+                                    name: "amount",
+                                    value: 120..123 @40 Int(
+                                        100,
+                                    ),
+                                },
+                                125..138 @40 Argument {
+                                    name: "currency",
+                                    value: 135..138 @40 Enum(
+                                        "EUR",
+                                    ),
+                                },
+                            ],
+                            directives: [],
+                            selection_set: SelectionSet {
+                                ty: "Int",
+                                selections: [],
+                            },
+                        },
+                    ),
+                ],
+            },
+        },
+    ),
+    named_operations: {},
+    fragments: {},
+}
diff --git a/crates/apollo-compiler/test_data/serializer/ok/0041_unquoted_string_for_custom_scalar.graphql b/crates/apollo-compiler/test_data/serializer/ok/0041_unquoted_string_for_custom_scalar.graphql
new file mode 100644
index 0000000..912b08a
--- /dev/null
+++ b/crates/apollo-compiler/test_data/serializer/ok/0041_unquoted_string_for_custom_scalar.graphql
@@ -0,0 +1,9 @@
+scalar Currency
+
+type Query {
+  convertToUSD(amount: Int!, currency: Currency!): Int!
+}
+
+query {
+  convertToUSD(amount: 100, currency: EUR)
+}