Repository: marshmallow-code/apispec
Pull request #828 (2023-03-06 19:53:15)

fix: resolve refs for callbacks
Schemas present in ```callbacks``` property in OAS3 should also be resolved to refs


Patch:
diff --git a/AUTHORS.rst b/AUTHORS.rst
index afe779f..02662ce 100644
--- a/AUTHORS.rst
+++ b/AUTHORS.rst
@@ -76,3 +76,4 @@ Contributors (chronological)
 - `<https://github.com/kasium>`_
 - Edwin Erdmanis `@vorticity <https://github.com/vorticity>`_
 - Mounier Florian `@paradoxxxzero <https://github.com/paradoxxxzero>`_
+- Renato Damas `@codectl <https://github.com/codectl>`_
diff --git a/src/apispec/core.py b/src/apispec/core.py
index 1a36b72..0dfe373 100644
--- a/src/apispec/core.py
+++ b/src/apispec/core.py
@@ -370,6 +370,11 @@ class Components:
                 self._resolve_refs_in_parameter_or_header(parameter)
                 parameters.append(parameter)
             operation["parameters"] = parameters
+        if "callbacks" in operation:
+            for callback in operation["callbacks"].values():
+                if isinstance(callback, dict):
+                    for path in callback.values():
+                        self.resolve_refs_in_path(path)
         if "requestBody" in operation:
             self._resolve_refs_in_request_body(operation["requestBody"])
         if "responses" in operation:


Test patch:
diff --git a/tests/test_core.py b/tests/test_core.py
index a5ff5f2..61674eb 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -23,7 +23,6 @@ from .utils import (
     build_ref,
 )
 
-
 description = "This is a sample Petstore server.  You can find out more "
 'about Swagger at <a href="http://swagger.wordnik.com">http://swagger.wordnik.com</a> '
 "or on irc.freenode.net, #swagger.  For this sample, you can use the api "
@@ -899,6 +898,53 @@ class TestPath(RefsSchemaTestMixin):
             schema = resp["content"]["application/json"]["schema"]
         assert schema == build_ref(spec, "schema", "PetSchema")
 
+    # callbacks only exists in OAS 3
+    @pytest.mark.parametrize("spec", ("3.0.0",), indirect=True)
+    def test_path_resolve_callbacks(self, spec):
+        parameter = {"name": "petId", "in": "query", "schema": "PetSchema"}
+        spec.path(
+            "/pet/{petId}",
+            operations={
+                "get": {
+                    "callbacks": {
+                        "onEvent": {
+                            "/callback/{petId}": {
+                                "post": {
+                                    "parameters": [parameter],
+                                    "requestBody": {
+                                        "content": {
+                                            "application/json": {"schema": "PetSchema"}
+                                        }
+                                    },
+                                    "responses": {
+                                        "200": {
+                                            "content": {
+                                                "application/json": {
+                                                    "schema": "PetSchema"
+                                                }
+                                            }
+                                        }
+                                    },
+                                }
+                            }
+                        }
+                    },
+                }
+            },
+        )
+        path = get_paths(spec)["/pet/{petId}"]
+        schema_ref = build_ref(spec, "schema", "PetSchema")
+        callback_op = path["get"]["callbacks"]["onEvent"]["/callback/{petId}"]["post"]
+        assert callback_op["parameters"][0]["schema"] == schema_ref
+        assert (
+            callback_op["requestBody"]["content"]["application/json"]["schema"]
+            == schema_ref
+        )
+        assert (
+            callback_op["responses"]["200"]["content"]["application/json"]["schema"]
+            == schema_ref
+        )
+
     # requestBody only exists in OAS 3
     @pytest.mark.parametrize("spec", ("3.0.0",), indirect=True)
     def test_path_resolve_request_body(self, spec):