test_repository.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. from unittest import mock
  2. import pytest
  3. from clean_python import (
  4. BadRequest,
  5. DoesNotExist,
  6. Filter,
  7. InMemoryGateway,
  8. Page,
  9. PageOptions,
  10. Repository,
  11. RootEntity,
  12. )
  13. class User(RootEntity):
  14. name: str
  15. @pytest.fixture
  16. def users():
  17. return [
  18. User.create(id=1, name="a"),
  19. User.create(id=2, name="b"),
  20. User.create(id=3, name="c"),
  21. ]
  22. class UserRepository(Repository[User]):
  23. pass
  24. @pytest.fixture
  25. def user_repository(users):
  26. return UserRepository(gateway=InMemoryGateway(data=[x.dict() for x in users]))
  27. @pytest.fixture
  28. def page_options():
  29. return PageOptions(limit=10, offset=0, order_by="id")
  30. def test_entity_attr(user_repository):
  31. assert user_repository.entity is User
  32. async def test_get(user_repository):
  33. actual = await user_repository.get(1)
  34. assert actual.name == "a"
  35. async def test_get_does_not_exist(user_repository):
  36. with pytest.raises(DoesNotExist):
  37. await user_repository.get(4)
  38. @mock.patch.object(Repository, "filter")
  39. async def test_all(filter_m, user_repository, page_options):
  40. filter_m.return_value = Page(total=0, items=[])
  41. assert await user_repository.all(page_options) is filter_m.return_value
  42. filter_m.assert_awaited_once_with([], params=page_options)
  43. async def test_add(user_repository):
  44. actual = await user_repository.add(User.create(name="d"))
  45. assert actual.name == "d"
  46. assert user_repository.gateway.data[4] == actual.dict()
  47. async def test_add_json(user_repository):
  48. actual = await user_repository.add({"name": "d"})
  49. assert actual.name == "d"
  50. assert user_repository.gateway.data[4] == actual.dict()
  51. async def test_add_json_validates(user_repository):
  52. with pytest.raises(BadRequest):
  53. await user_repository.add({"id": "d"})
  54. async def test_update(user_repository):
  55. actual = await user_repository.update(id=2, values={"name": "d"})
  56. assert actual.name == "d"
  57. assert user_repository.gateway.data[2] == actual.dict()
  58. async def test_update_does_not_exist(user_repository):
  59. with pytest.raises(DoesNotExist):
  60. await user_repository.update(id=4, values={"name": "d"})
  61. async def test_update_validates(user_repository):
  62. with pytest.raises(BadRequest):
  63. await user_repository.update(id=2, values={"id": 6})
  64. async def test_remove(user_repository):
  65. assert await user_repository.remove(2)
  66. assert 2 not in user_repository.gateway.data
  67. async def test_remove_does_not_exist(user_repository):
  68. assert not await user_repository.remove(4)
  69. async def test_upsert_updates(user_repository):
  70. actual = await user_repository.upsert(User.create(id=2, name="d"))
  71. assert actual.name == "d"
  72. assert user_repository.gateway.data[2] == actual.dict()
  73. async def test_upsert_adds(user_repository):
  74. actual = await user_repository.upsert(User.create(id=4, name="d"))
  75. assert actual.name == "d"
  76. assert user_repository.gateway.data[4] == actual.dict()
  77. @mock.patch.object(InMemoryGateway, "count")
  78. async def test_filter(count_m, user_repository, users):
  79. actual = await user_repository.filter([Filter(field="name", values=["b"])])
  80. assert actual == Page(total=1, items=[users[1]], limit=None, offest=None)
  81. assert not count_m.called
  82. @mock.patch.object(InMemoryGateway, "count")
  83. async def test_filter_with_pagination(count_m, user_repository, users, page_options):
  84. actual = await user_repository.filter(
  85. [Filter(field="name", values=["b"])], page_options
  86. )
  87. assert actual == Page(
  88. total=1, items=[users[1]], limit=page_options.limit, offset=page_options.offset
  89. )
  90. assert not count_m.called
  91. @pytest.mark.parametrize(
  92. "page_options",
  93. [
  94. PageOptions(limit=3, offset=0, order_by="id"),
  95. PageOptions(limit=10, offset=1, order_by="id"),
  96. ],
  97. )
  98. @mock.patch.object(InMemoryGateway, "count")
  99. async def test_filter_with_pagination_calls_count(
  100. count_m, user_repository, users, page_options
  101. ):
  102. count_m.return_value = 123
  103. actual = await user_repository.filter([], page_options)
  104. assert actual == Page(
  105. total=count_m.return_value,
  106. items=users[page_options.offset :],
  107. limit=page_options.limit,
  108. offset=page_options.offset,
  109. )
  110. assert count_m.called
  111. @mock.patch.object(Repository, "filter")
  112. async def test_by(filter_m, user_repository, page_options):
  113. filter_m.return_value = Page(total=0, items=[])
  114. assert await user_repository.by("name", "b", page_options) is filter_m.return_value
  115. filter_m.assert_awaited_once_with(
  116. [Filter(field="name", values=["b"])], params=page_options
  117. )
  118. @mock.patch.object(InMemoryGateway, "count")
  119. async def test_count(gateway_count, user_repository):
  120. assert await user_repository.count("foo") is gateway_count.return_value
  121. gateway_count.assert_awaited_once_with("foo")
  122. @mock.patch.object(InMemoryGateway, "exists")
  123. async def test_exists(gateway_exists, user_repository):
  124. assert await user_repository.exists("foo") is gateway_exists.return_value
  125. gateway_exists.assert_awaited_once_with("foo")