Repository: striglia/pyramid_swagger
Pull request #242 (2019-05-24 16:17:51)

Fix pyramid swagger renderer if missing schema
Fixes: #236 

In order to prevent regression a specific unit and acceptance test has been added to the code base


Patch:
diff --git a/pyramid_swagger/renderer.py b/pyramid_swagger/renderer.py
index b83b019..37d78cb 100644
--- a/pyramid_swagger/renderer.py
+++ b/pyramid_swagger/renderer.py
@@ -35,10 +35,7 @@ class PyramidSwaggerRendererFactory(object):
                 schema_object_spec=response_spec['schema'],
                 value=response_object,
             )
-        except MatchingResponseNotFound:
-            # Response specs not found
-            return response_object
-        except SwaggerMappingError:
+        except (MatchingResponseNotFound, SwaggerMappingError, KeyError):
             # marshaling process failed
             return response_object
 


Test patch:
diff --git a/tests/acceptance/app/__init__.py b/tests/acceptance/app/__init__.py
index 3f2ea98..3df6beb 100644
--- a/tests/acceptance/app/__init__.py
+++ b/tests/acceptance/app/__init__.py
@@ -51,6 +51,7 @@ def date_view(request):
 
 
 @view_config(route_name='post_endpoint_with_optional_body', request_method='POST', renderer='pyramid_swagger')
+@view_config(route_name='sample_no_response_schema', request_method='GET', renderer='pyramid_swagger')
 def post_endpoint_with_optional_body(request):
     return request.content_length
 
@@ -71,10 +72,7 @@ def main(global_config, **settings):
         '/sample/nonstring/{int_arg}/{float_arg}/{boolean_arg}',
     )
     config.add_route('standard', '/sample/{path_arg}/resource')
-    config.add_route(
-        'get_with_non_string_query_args',
-        '/get_with_non_string_query_args',
-    )
+    config.add_route('get_with_non_string_query_args', '/get_with_non_string_query_args')
     config.add_route('post_with_primitive_body', '/post_with_primitive_body')
     config.add_route('post_with_form_params', '/post_with_form_params')
     config.add_route('post_with_file_upload', '/post_with_file_upload')
@@ -94,3 +92,4 @@ def main(global_config, **settings):
 def include_samples(config):
     config.add_route('sample_header', '/header')
     config.add_route('sample_authentication', '/authentication')
+    config.add_route('sample_no_response_schema', '/no_response_schema')
diff --git a/tests/acceptance/request_test.py b/tests/acceptance/request_test.py
index 6b67e6d..b35ee1e 100644
--- a/tests/acceptance/request_test.py
+++ b/tests/acceptance/request_test.py
@@ -315,3 +315,9 @@ def test_request_to_authenticated_endpoint_without_authentication():
         expect_errors=True,
     )
     assert response.status_code == 401
+
+
+def test_request_to_endpoint_with_no_response_schema():
+    app = build_test_app(swagger_versions=['2.0'])
+    response = app.get('/sample/no_response_schema')
+    assert response.status_code == 200
diff --git a/tests/renderer_test.py b/tests/renderer_test.py
index 1071bd6..84f313e 100644
--- a/tests/renderer_test.py
+++ b/tests/renderer_test.py
@@ -97,6 +97,25 @@ class TestPyramidSwaggerRendererFactoryUnitTest(object):
         )
         assert rendered_value == self.external_renderer_factory.return_value.return_value
 
+    def test_rendering_response_without_schema(self, mock_get_response_spec, mock_marshal_schema_object):
+        renderer_factory = PyramidSwaggerRendererFactory(renderer_factory=self.external_renderer_factory)
+        mock_get_response_spec.return_value = {'200': {'description': ''}}
+
+        renderer = renderer_factory(info=self.info)
+        rendered_value = renderer(self.value_to_render, self.mock_system)
+
+        self.external_renderer_factory.assert_called_once_with(self.info)
+        mock_get_response_spec.assert_called_once_with(
+            op=self.mock_request.operation,
+            status_code=self.mock_request.response.status_code,
+        )
+        assert not mock_marshal_schema_object.called
+        self.external_renderer_factory.return_value.assert_called_once_with(
+            self.value_to_render,
+            self.mock_system,
+        )
+        assert rendered_value == self.external_renderer_factory.return_value.return_value
+
     def test_rendering_error_during_marshaling(self, mock_get_response_spec, mock_marshal_schema_object):
         renderer_factory = PyramidSwaggerRendererFactory(renderer_factory=self.external_renderer_factory)
         mock_marshal_schema_object.side_effect = SwaggerMappingError
diff --git a/tests/sample_schemas/good_app/swagger.json b/tests/sample_schemas/good_app/swagger.json
index 3ca8d35..b8eec42 100644
--- a/tests/sample_schemas/good_app/swagger.json
+++ b/tests/sample_schemas/good_app/swagger.json
@@ -187,6 +187,17 @@
         ]
       }
     },
+    "/sample/no_response_schema": {
+      "get": {
+        "responses": {
+          "200": {
+            "description": "Body presence status"
+          }
+        },
+        "description": "",
+        "operationId": "sample_no_response_schema"
+      }
+    },
     "/sample": {
       "get": {
         "responses": {