schemadoc_diff/checker/
added_required_parameter_check.rs1use std::cell::RefCell;
2
3use crate::checker::{ValidationIssue, ValidationIssuer};
4use crate::core::{DiffResult, VecDiff};
5use crate::path_pointer::PathPointer;
6use crate::schema_diff::{MayBeRefDiff, OperationDiff, ParameterDiff};
7
8use crate::visitor::DiffVisitor;
9
10pub struct AddedRequiredParameterCheck {
11 pointers: RefCell<Vec<PathPointer>>,
12}
13
14impl<'s> DiffVisitor<'s> for AddedRequiredParameterCheck {
15 fn visit_operation(
16 &self,
17 pointer: &PathPointer,
18 _: &str,
19 _: &'s DiffResult<OperationDiff>,
20 ) -> bool {
21 pointer.is_updated()
22 }
23
24 fn visit_parameters(
25 &self,
26 pointer: &PathPointer,
27 _: &'s DiffResult<VecDiff<MayBeRefDiff<ParameterDiff>>>,
28 ) -> bool {
29 pointer.is_updated()
30 }
31
32 fn visit_parameter(
33 &self,
34 pointer: &PathPointer,
35 parameter_diff_result: &'s DiffResult<ParameterDiff>,
36 ) -> bool {
37 if !pointer.is_upserted() {
39 return false;
40 }
41
42 if let Some(parameter_diff) = parameter_diff_result.get() {
43 if parameter_diff.required.is_upserted() {
44 if let Some(required) = parameter_diff.required.get() {
45 if *required {
46 self.pointers.borrow_mut().push(pointer.clone())
47 }
48 }
49 }
50 }
51
52 false
53 }
54}
55
56impl Default for AddedRequiredParameterCheck {
57 fn default() -> Self {
58 AddedRequiredParameterCheck {
59 pointers: RefCell::new(vec![]),
60 }
61 }
62}
63
64impl<'s> ValidationIssuer<'s> for AddedRequiredParameterCheck {
65 fn id(&self) -> &'static str {
66 "added-required-parameter"
67 }
68
69 fn visitor(&self) -> &dyn DiffVisitor<'s> {
70 self
71 }
72
73 fn issues(&self) -> Option<Vec<ValidationIssue>> {
74 let pointers = std::mem::take(&mut *self.pointers.borrow_mut());
75
76 let issues = pointers
77 .into_iter()
78 .map(|path| ValidationIssue::new(path, self.id(), true))
79 .collect::<Vec<ValidationIssue>>();
80
81 Some(issues)
82 }
83}
84
85#[cfg(test)]
86mod tests {
87 use crate::checker::added_required_parameter_check::AddedRequiredParameterCheck;
88 use crate::checker::ValidationIssuer;
89 use crate::get_schema_diff;
90 use crate::schema::HttpSchema;
91 use crate::schemas::openapi303::schema::OpenApi303;
92
93 #[test]
94 fn test_added_required_parameter_check() {
95 let src_schema: HttpSchema = serde_json::from_str::<OpenApi303>(include_str!(
96 "../../data/checks/added-required-parameter/schema-with-parameters.json"
97 ))
98 .unwrap()
99 .into();
100
101 let tgt_schema: HttpSchema = serde_json::from_str::<OpenApi303>(include_str!(
102 "../../data/checks/added-required-parameter/schema-with-update-parameters.json"
103 ))
104 .unwrap()
105 .into();
106
107 let diff = get_schema_diff(src_schema, tgt_schema);
108
109 let checker = AddedRequiredParameterCheck::default();
110 crate::visitor::dispatch_visitor(diff.get().unwrap(), &checker);
111 let issues = checker.issues().unwrap();
112
113 assert_eq!(issues.len(), 2);
114 assert_eq!(
116 issues.get(0).unwrap().path.get_path(),
117 "paths//test/get/parameters/1",
118 );
119 assert_eq!(
121 issues.get(1).unwrap().path.get_path(),
122 "paths//test/get/parameters/5",
123 );
124 }
125}