test_resource.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. import pytest
  2. from fastapi.routing import APIRouter
  3. from clean_python.fastapi import APIVersion
  4. from clean_python.fastapi import get
  5. from clean_python.fastapi import Resource
  6. from clean_python.fastapi import Stability
  7. from clean_python.fastapi import v
  8. def test_subclass():
  9. class Cls(Resource, version=v(1), name="foo"):
  10. pass
  11. for obj in (Cls, Cls()):
  12. assert obj.name == "foo"
  13. assert obj.version == v(1)
  14. def test_get_router_no_endpoints():
  15. class Cls(Resource, version=v(1)):
  16. pass
  17. router = Cls().get_router(v(1))
  18. assert isinstance(router, APIRouter)
  19. assert len(router.routes) == 0
  20. def test_get_router_other_version():
  21. class TestResource(Resource, version=v(1), name="testing"):
  22. @get("/foo/{id}")
  23. def get_test(self, id: int):
  24. return "ok"
  25. with pytest.raises(AssertionError):
  26. TestResource().get_router(v(2))
  27. def test_get_router():
  28. class TestResource(Resource, version=v(1), name="testing"):
  29. @get("/foo/{id}")
  30. def get_test(self, id: int):
  31. return "ok"
  32. resource = TestResource()
  33. router = resource.get_router(v(1))
  34. assert len(router.routes) == 1
  35. route = router.routes[0]
  36. assert route.path == "/foo/{id}"
  37. assert route.operation_id == "get_test"
  38. assert route.name == "v1/get_test"
  39. assert route.tags == ["testing"]
  40. assert route.methods == {"GET"}
  41. # 'self' is missing from the parameters
  42. assert list(route.param_convertors.keys()) == ["id"]
  43. def test_get_openapi_tag():
  44. class Cls(Resource, version=v(1), name="foo"):
  45. """Docstring"""
  46. actual = Cls().get_openapi_tag()
  47. assert actual.name == "foo"
  48. assert actual.description == "Docstring"
  49. def test_v():
  50. assert v(1, "alpha") == APIVersion(version=1, stability=Stability.ALPHA)
  51. @pytest.mark.parametrize(
  52. "version,expected",
  53. [(v(1, "beta"), "v1-beta"), (v(2), "v2"), (v(3, "alpha"), "v3-alpha")],
  54. )
  55. def test_api_version_prefix(version, expected):
  56. assert version.prefix == expected
  57. def test_url_path_for():
  58. class TestResource(Resource, version=v(1), name="testing"):
  59. @get("/foo/{id}")
  60. def get_test(self, id: int):
  61. return "ok"
  62. resource = TestResource()
  63. router = resource.get_router(v(1))
  64. assert router.url_path_for("v1/get_test", id=2) == "/foo/2"
  65. def test_with_version():
  66. class TestResource(Resource, version=v(1), name="testing"):
  67. """Foo"""
  68. @get("/foo/{id}")
  69. def get_test(self, id: int):
  70. return "ok"
  71. resource_cls = TestResource.with_version(v(1, "beta"))
  72. assert resource_cls.version == v(1, "beta")
  73. assert resource_cls.name == "testing"
  74. assert resource_cls.__doc__ == "Foo"
  75. assert resource_cls.__bases__ == (TestResource,)
  76. def test_get_less_stable():
  77. class V1(Resource, version=v(1), name="testing"):
  78. pass
  79. class V1Beta(V1, version=v(1, "beta"), name="testing"):
  80. pass
  81. resources = {x.version: x() for x in [V1, V1Beta]}
  82. assert resources[v(1)].get_less_stable(resources) is resources[v(1, "beta")]
  83. v1_alpha = resources[v(1, "beta")].get_less_stable(resources)
  84. assert v1_alpha.version == v(1, "alpha")
  85. assert v1_alpha.__class__.__bases__ == (V1Beta,)
  86. def test_get_less_stable_no_subclass():
  87. class V1(Resource, version=v(1), name="testing"):
  88. pass
  89. class V1Beta(Resource, version=v(1, "beta"), name="testing"):
  90. pass
  91. resources = {x.version: x() for x in [V1, V1Beta]}
  92. with pytest.raises(RuntimeError):
  93. resources[v(1)].get_less_stable(resources)