test_resource.py 3.4 KB

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