From 0c99f1618511ff4578885b12f7fc5c993893d500 Mon Sep 17 00:00:00 2001 From: Mat Gadd Date: Fri, 14 Jun 2019 17:28:13 +0100 Subject: [PATCH 1/2] Only include description in param and header when it has a value, else the resulting document fails validation --- flask_restplus/namespace.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/flask_restplus/namespace.py b/flask_restplus/namespace.py index b3c1c05a..1bb52271 100644 --- a/flask_restplus/namespace.py +++ b/flask_restplus/namespace.py @@ -267,9 +267,10 @@ def param(self, name, description=None, _in='query', **kwargs): :param str description: a small description :param str _in: the parameter location `(query|header|formData|body|cookie)` ''' - param = kwargs + param = kwargs.copy() param['in'] = _in - param['description'] = description + if description is not None: + param['description'] = description return self.doc(params={name: param}) def response(self, code, description, model=None, **kwargs): @@ -291,8 +292,9 @@ def header(self, name, description=None, **kwargs): :param str description: a description about the header ''' - header = {'description': description} - header.update(kwargs) + header = kwargs.copy() + if description is not None: + header['description'] = description return self.doc(headers={name: header}) def produces(self, mimetypes): From a3c9114c94cb1c208ab7f25e66a0d4558d313034 Mon Sep 17 00:00:00 2001 From: Mat Gadd Date: Mon, 17 Jun 2019 14:35:55 +0100 Subject: [PATCH 2/2] Add tests confirming that the `description` key is omitted when not given a value --- tests/test_swagger.py | 52 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/tests/test_swagger.py b/tests/test_swagger.py index cd28fd6f..9b037898 100644 --- a/tests/test_swagger.py +++ b/tests/test_swagger.py @@ -842,6 +842,25 @@ def get(self, age): assert parameter['in'] == 'formData' assert parameter['description'] == 'A query string' + def test_explicit_parameters_with_decorator_no_description(self, api, client): + @api.route('/name/') + class ByNameResource(restplus.Resource): + @api.param('q', type='string', _in='formData') + def get(self, age): + return {} + + data = client.get_specs() + assert '/name/' in data['paths'] + + op = data['paths']['/name/']['get'] + assert len(op['parameters']) == 1 + + parameter = op['parameters'][0] + assert parameter['name'] == 'q' + assert parameter['type'] == 'string' + assert parameter['in'] == 'formData' + assert 'description' not in parameter + def test_class_explicit_parameters(self, api, client): @api.route('/name//', endpoint='by-name', doc={ 'params': { @@ -876,6 +895,39 @@ def get(self, age): assert parameter['in'] == 'query' assert parameter['description'] == 'A query string' + def test_class_explicit_parameters_no_description(self, api, client): + @api.route('/name//', endpoint='by-name', doc={ + 'params': { + 'q': { + 'type': 'string', + 'in': 'query', + } + } + }) + class ByNameResource(restplus.Resource): + def get(self, age): + return {} + + data = client.get_specs() + assert '/name/{age}/' in data['paths'] + + path = data['paths']['/name/{age}/'] + assert len(path['parameters']) == 2 + + by_name = dict((p['name'], p) for p in path['parameters']) + + parameter = by_name['age'] + assert parameter['name'] == 'age' + assert parameter['type'] == 'integer' + assert parameter['in'] == 'path' + assert parameter['required'] is True + + parameter = by_name['q'] + assert parameter['name'] == 'q' + assert parameter['type'] == 'string' + assert parameter['in'] == 'query' + assert 'description' not in parameter + def test_explicit_parameters_override(self, api, client): @api.route('/name//', endpoint='by-name', doc={ 'params': {