graphql_tools/validation/rules/
known_fragment_names.rs1use super::ValidationRule;
2use crate::ast::{visit_document, OperationVisitor, OperationVisitorContext};
3use crate::static_graphql::query::*;
4use crate::validation::utils::{ValidationError, ValidationErrorContext};
5
6pub struct KnownFragmentNames;
13
14impl Default for KnownFragmentNames {
15 fn default() -> Self {
16 Self::new()
17 }
18}
19
20impl KnownFragmentNames {
21 pub fn new() -> Self {
22 KnownFragmentNames
23 }
24}
25
26impl<'a> OperationVisitor<'a, ValidationErrorContext> for KnownFragmentNames {
27 fn enter_fragment_spread(
28 &mut self,
29 visitor_context: &mut OperationVisitorContext,
30 user_context: &mut ValidationErrorContext,
31 fragment_spread: &FragmentSpread,
32 ) {
33 if !visitor_context
34 .known_fragments
35 .contains_key(fragment_spread.fragment_name.as_str())
36 {
37 user_context.report_error(ValidationError {
38 error_code: self.error_code(),
39 locations: vec![fragment_spread.position],
40 message: format!("Unknown fragment \"{}\".", fragment_spread.fragment_name),
41 })
42 }
43 }
44}
45
46impl ValidationRule for KnownFragmentNames {
47 fn error_code<'a>(&self) -> &'a str {
48 "KnownFragmentNames"
49 }
50
51 fn validate(
52 &self,
53 ctx: &mut OperationVisitorContext,
54 error_collector: &mut ValidationErrorContext,
55 ) {
56 visit_document(
57 &mut KnownFragmentNames::new(),
58 ctx.operation,
59 ctx,
60 error_collector,
61 );
62 }
63}
64
65#[test]
66fn valid_fragment() {
67 use crate::validation::test_utils::*;
68
69 let mut plan = create_plan_from_rule(Box::new(KnownFragmentNames {}));
70 let errors = test_operation_with_schema(
71 "{
72 human(id: 4) {
73 ...HumanFields1
74 ... on Human {
75 ...HumanFields2
76 }
77 ... {
78 name
79 }
80 }
81 }
82 fragment HumanFields1 on Human {
83 name
84 ...HumanFields3
85 }
86 fragment HumanFields2 on Human {
87 name
88 }
89 fragment HumanFields3 on Human {
90 name
91 }",
92 TEST_SCHEMA,
93 &mut plan,
94 );
95
96 assert_eq!(get_messages(&errors).len(), 0);
97}
98
99#[test]
100fn invalid_fragment() {
101 use crate::validation::test_utils::*;
102
103 let mut plan = create_plan_from_rule(Box::new(KnownFragmentNames {}));
104 let errors = test_operation_with_schema(
105 "{
106 human(id: 4) {
107 ...UnknownFragment1
108 ... on Human {
109 ...UnknownFragment2
110 }
111 }
112 }
113 fragment HumanFields on Human {
114 name
115 ...UnknownFragment3
116 }",
117 TEST_SCHEMA,
118 &mut plan,
119 );
120
121 let messages = get_messages(&errors);
122 assert_eq!(messages.len(), 3);
123 assert_eq!(
124 messages,
125 vec![
126 "Unknown fragment \"UnknownFragment1\".",
127 "Unknown fragment \"UnknownFragment2\".",
128 "Unknown fragment \"UnknownFragment3\".",
129 ]
130 );
131}