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