summaryrefslogtreecommitdiffstats
path: root/src/pybind/mgr/dashboard/tests/test_docs.py
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:54:28 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:54:28 +0000
commite6918187568dbd01842d8d1d2c808ce16a894239 (patch)
tree64f88b554b444a49f656b6c656111a145cbbaa28 /src/pybind/mgr/dashboard/tests/test_docs.py
parentInitial commit. (diff)
downloadceph-e6918187568dbd01842d8d1d2c808ce16a894239.tar.xz
ceph-e6918187568dbd01842d8d1d2c808ce16a894239.zip
Adding upstream version 18.2.2.upstream/18.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/pybind/mgr/dashboard/tests/test_docs.py')
-rw-r--r--src/pybind/mgr/dashboard/tests/test_docs.py240
1 files changed, 240 insertions, 0 deletions
diff --git a/src/pybind/mgr/dashboard/tests/test_docs.py b/src/pybind/mgr/dashboard/tests/test_docs.py
new file mode 100644
index 000000000..ded0c140e
--- /dev/null
+++ b/src/pybind/mgr/dashboard/tests/test_docs.py
@@ -0,0 +1,240 @@
+# # -*- coding: utf-8 -*-
+
+import unittest
+
+from ..api.doc import SchemaType
+from ..controllers import ENDPOINT_MAP, APIDoc, APIRouter, Endpoint, EndpointDoc, RESTController
+from ..controllers._version import APIVersion
+from ..controllers.docs import Docs
+from ..tests import ControllerTestCase
+
+
+# Dummy controller and endpoint that can be assigned with @EndpointDoc and @GroupDoc
+@APIDoc("Group description", group="FooGroup")
+@APIRouter("/doctest/", secure=False)
+class DecoratedController(RESTController):
+ RESOURCE_ID = 'doctest'
+
+ @EndpointDoc(
+ description="Endpoint description",
+ group="BarGroup",
+ parameters={
+ 'parameter': (int, "Description of parameter"),
+ },
+ responses={
+ 200: [{
+ 'my_prop': (str, '200 property desc.')
+ }],
+ 202: {
+ 'my_prop': (str, '202 property desc.')
+ },
+ },
+ )
+ @Endpoint(json_response=False)
+ @RESTController.Resource('PUT', version=APIVersion(0, 1))
+ def decorated_func(self, parameter):
+ pass
+
+ @RESTController.MethodMap(version=APIVersion(0, 1))
+ def list(self):
+ pass
+
+
+# To assure functionality of @EndpointDoc, @GroupDoc
+class DocDecoratorsTest(ControllerTestCase):
+ @classmethod
+ def setup_server(cls):
+ cls.setup_controllers([DecoratedController, Docs], "/test")
+
+ def test_group_info_attr(self):
+ test_ctrl = DecoratedController()
+ self.assertTrue(hasattr(test_ctrl, 'doc_info'))
+ self.assertIn('tag_descr', test_ctrl.doc_info)
+ self.assertIn('tag', test_ctrl.doc_info)
+
+ def test_endpoint_info_attr(self):
+ test_ctrl = DecoratedController()
+ test_endpoint = test_ctrl.decorated_func
+ self.assertTrue(hasattr(test_endpoint, 'doc_info'))
+ self.assertIn('summary', test_endpoint.doc_info)
+ self.assertIn('tag', test_endpoint.doc_info)
+ self.assertIn('parameters', test_endpoint.doc_info)
+ self.assertIn('response', test_endpoint.doc_info)
+
+
+# To assure functionality of Docs.py
+# pylint: disable=protected-access
+class DocsTest(ControllerTestCase):
+ @classmethod
+ def setup_server(cls):
+ ENDPOINT_MAP.clear()
+ cls.setup_controllers([DecoratedController, Docs], "/test")
+
+ def test_type_to_str(self):
+ self.assertEqual(Docs()._type_to_str(str), str(SchemaType.STRING))
+ self.assertEqual(Docs()._type_to_str(int), str(SchemaType.INTEGER))
+ self.assertEqual(Docs()._type_to_str(bool), str(SchemaType.BOOLEAN))
+ self.assertEqual(Docs()._type_to_str(list), str(SchemaType.ARRAY))
+ self.assertEqual(Docs()._type_to_str(tuple), str(SchemaType.ARRAY))
+ self.assertEqual(Docs()._type_to_str(float), str(SchemaType.NUMBER))
+ self.assertEqual(Docs()._type_to_str(object), str(SchemaType.OBJECT))
+ self.assertEqual(Docs()._type_to_str(None), str(SchemaType.OBJECT))
+
+ def test_gen_paths(self):
+ outcome = Docs().gen_paths(False)['/api/doctest//{doctest}/decorated_func']['put']
+ self.assertIn('tags', outcome)
+ self.assertIn('summary', outcome)
+ self.assertIn('parameters', outcome)
+ self.assertIn('responses', outcome)
+
+ expected_response_content = {
+ '200': {
+ APIVersion(0, 1).to_mime_type(): {
+ 'schema': {'type': 'array',
+ 'items': {'type': 'object', 'properties': {
+ 'my_prop': {
+ 'type': 'string',
+ 'description': '200 property desc.'}}},
+ 'required': ['my_prop']}}},
+ '202': {
+ APIVersion(0, 1).to_mime_type(): {
+ 'schema': {'type': 'object',
+ 'properties': {'my_prop': {
+ 'type': 'string',
+ 'description': '202 property desc.'}},
+ 'required': ['my_prop']}}
+ }
+ }
+ # Check that a schema of type 'array' is received in the response.
+ self.assertEqual(expected_response_content['200'], outcome['responses']['200']['content'])
+ # Check that a schema of type 'object' is received in the response.
+ self.assertEqual(expected_response_content['202'], outcome['responses']['202']['content'])
+
+ def test_gen_method_paths(self):
+ outcome = Docs().gen_paths(False)['/api/doctest/']['get']
+
+ self.assertEqual({APIVersion(0, 1).to_mime_type(): {'type': 'object'}},
+ outcome['responses']['200']['content'])
+
+ def test_gen_paths_all(self):
+ paths = Docs().gen_paths(False)
+ for key in paths:
+ self.assertTrue(any(base in key.split('/')[1] for base in ['api', 'ui-api']))
+
+ def test_gen_tags(self):
+ outcome = Docs._gen_tags(False)
+ self.assertEqual([{'description': 'Group description', 'name': 'FooGroup'}], outcome)
+
+
+class TestEndpointDocWrapper(unittest.TestCase):
+ def test_wrong_param_types(self):
+ with self.assertRaises(Exception):
+ EndpointDoc(description=False)
+ with self.assertRaises(Exception):
+ EndpointDoc(group=False)
+ with self.assertRaises(Exception):
+ EndpointDoc(parameters='wrong parameters')
+ with self.assertRaises(Exception):
+ EndpointDoc(responses='wrong response')
+
+ def dummy_func():
+ pass
+ with self.assertRaises(Exception):
+ EndpointDoc(parameters={'parameter': 'wrong parameter'})(dummy_func)
+
+ def test_split_dict(self):
+ edoc = EndpointDoc()
+ data = {
+ 'name1': (int, 'description1'),
+ 'dict_param': ({'name2': (int, 'description2')}, 'description_dict'),
+ 'list_param': ([int, float], 'description_list')
+ }
+ expected = [
+ {
+ 'name': 'name1',
+ 'description': 'description1',
+ 'required': True,
+ 'nested': False,
+ 'type': int
+ },
+ {
+ 'name': 'dict_param',
+ 'description': 'description_dict',
+ 'required': True,
+ 'nested': False,
+ 'type': dict,
+ 'nested_params': [
+ {
+ 'name': 'name2',
+ 'description': 'description2',
+ 'required': True,
+ 'nested': True,
+ 'type': int
+ }
+ ]
+ },
+ {
+ 'name': 'list_param',
+ 'description':
+ 'description_list',
+ 'required': True,
+ 'nested': False,
+ 'type': [int, float]
+ }
+ ]
+
+ res = edoc._split_dict(data, False)
+ self.assertEqual(res, expected)
+
+ def test_split_param(self):
+ edoc = EndpointDoc()
+ name = 'foo'
+ p_type = int
+ description = 'description'
+ default_value = 1
+ expected = {
+ 'name': name,
+ 'description': description,
+ 'required': True,
+ 'nested': False,
+ 'default': default_value,
+ 'type': p_type,
+ }
+ res = edoc._split_param(name, p_type, description, default_value=default_value)
+ self.assertEqual(res, expected)
+
+ def test_split_param_nested(self):
+ edoc = EndpointDoc()
+ name = 'foo'
+ p_type = {'name2': (int, 'description2')}, 'description_dict'
+ description = 'description'
+ default_value = 1
+ expected = {
+ 'name': name,
+ 'description': description,
+ 'required': True,
+ 'nested': True,
+ 'default': default_value,
+ 'type': type(p_type),
+ 'nested_params': [
+ {
+ 'name': 'name2',
+ 'description': 'description2',
+ 'required': True,
+ 'nested': True,
+ 'type': int
+ }
+ ]
+ }
+ res = edoc._split_param(name, p_type, description, default_value=default_value,
+ nested=True)
+ self.assertEqual(res, expected)
+
+ def test_split_list(self):
+ edoc = EndpointDoc()
+ data = [('foo', int), ('foo', float)]
+ expected = []
+
+ res = edoc._split_list(data, True)
+
+ self.assertEqual(res, expected)