Repository: mirumee/ariadne

Issue:
No Error Raised for Missing directive definition
I have the following type defs:
```python
type_defs = gql(
    """
    directive @authonly on FIELD_DEFINITION

    type Query {
        hello: String! @authonly,
    }
"""
)
```

And then when I created and use the schema using (notice the typo in directive name):
```python
schema = make_executable_schema(
    type_defs, [query], directives={'auxthonly': AuthOnlyDirective}
)
```

no exception raised to indicate that the directive `authonly` is undefined or that `auxthonly` is undeclared.

Hints from issue comments:
@rafalp: I agree, we could raise an error when this happens!

Solution patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6268b2e..6bdf3a0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,10 @@
 # CHANGELOG
 
+## 0.24 (UNRELEASED)
+
+- Added validation for directive declarations in `make_executable_schema` to prevent schema creation with undeclared directives.
+
+
 ## 0.23 (2024-03-18)
 
 - Added `execute_get_queries` setting to the `GraphQL` apps that controls execution of the GraphQL "query" operations made with GET requests. Defaults to `False`.
diff --git a/ariadne/schema_visitor.py b/ariadne/schema_visitor.py
index 5300c88..7d76d7d 100644
--- a/ariadne/schema_visitor.py
+++ b/ariadne/schema_visitor.py
@@ -468,6 +468,15 @@ class SchemaDirectiveVisitor(SchemaVisitor):
 
         each(schema.directives, _add_directive)
 
+        missing_directives = [
+            name for name in directive_visitors if name not in declared_directives
+        ]
+
+        if missing_directives:
+            raise ValueError(
+                f"Missing directive declarations for: {', '.join(missing_directives)}"
+            )
+
         #  If the visitor subclass overrides get_directive_declaration, and it
         #  returns a non-null GraphQLDirective, use that instead of any directive
         #  declared in the schema itself. Reasoning: if a SchemaDirectiveVisitor


Test patch:
diff --git a/tests/test_directives.py b/tests/test_directives.py
index 85440b4..3759b57 100644
--- a/tests/test_directives.py
+++ b/tests/test_directives.py
@@ -178,6 +178,21 @@ def test_directive_raises_type_error_if_required_argument_is_not_given():
         make_executable_schema(type_defs, directives={"test": ReturnValueDirective})
 
 
+def test_directive_raises_type_error_if_there_is_typo():
+    type_defs = """
+        directive @test on FIELD_DEFINITION
+
+        type Query {
+            hello: String! @test,
+        }
+    """
+
+    with pytest.raises(ValueError):
+        make_executable_schema(
+            type_defs, directives={"test_typo": ReturnValueDirective}
+        )
+
+
 def test_can_implement_unique_id_directive():
     type_defs = """
         directive @uniqueID(name: String, from: [String]) on OBJECT