test_gateway.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. from datetime import datetime, timezone
  2. from unittest import mock
  3. import pytest
  4. from clean_python import (
  5. AlreadyExists,
  6. Conflict,
  7. DoesNotExist,
  8. Filter,
  9. InMemoryGateway,
  10. PageOptions,
  11. )
  12. @pytest.fixture
  13. def in_memory_gateway():
  14. return InMemoryGateway(
  15. data=[
  16. {"id": 1, "name": "a"},
  17. {"id": 2, "name": "b"},
  18. {"id": 3, "name": "c"},
  19. ]
  20. )
  21. async def test_get(in_memory_gateway):
  22. actual = await in_memory_gateway.get(1)
  23. assert actual == in_memory_gateway.data[1]
  24. async def test_get_none(in_memory_gateway):
  25. actual = await in_memory_gateway.get(4)
  26. assert actual is None
  27. async def test_add(in_memory_gateway):
  28. record = {"id": 5, "name": "d"}
  29. await in_memory_gateway.add(record)
  30. assert in_memory_gateway.data[5] == record
  31. async def test_add_id_autoincrement(in_memory_gateway):
  32. record = {"name": "d"}
  33. await in_memory_gateway.add(record)
  34. assert in_memory_gateway.data[4] == {"id": 4, "name": "d"}
  35. async def test_add_id_exists(in_memory_gateway):
  36. with pytest.raises(AlreadyExists):
  37. await in_memory_gateway.add({"id": 3})
  38. async def test_update(in_memory_gateway):
  39. record = {"id": 3, "name": "d"}
  40. await in_memory_gateway.update(record)
  41. assert in_memory_gateway.data[3] == record
  42. async def test_update_no_id(in_memory_gateway):
  43. with pytest.raises(DoesNotExist):
  44. await in_memory_gateway.update({"no": "id"})
  45. async def test_update_does_not_exist(in_memory_gateway):
  46. with pytest.raises(DoesNotExist):
  47. await in_memory_gateway.update({"id": 4})
  48. async def test_upsert(in_memory_gateway):
  49. record = {"id": 3, "name": "d"}
  50. await in_memory_gateway.upsert(record)
  51. assert in_memory_gateway.data[3] == record
  52. async def test_upsert_no_id(in_memory_gateway):
  53. await in_memory_gateway.upsert({"name": "x"})
  54. assert in_memory_gateway.data[4] == {"id": 4, "name": "x"}
  55. async def test_upsert_does_add(in_memory_gateway):
  56. await in_memory_gateway.upsert({"id": 4, "name": "x"})
  57. assert in_memory_gateway.data[4] == {"id": 4, "name": "x"}
  58. async def test_remove(in_memory_gateway):
  59. assert await in_memory_gateway.remove(1)
  60. assert 1 not in in_memory_gateway.data
  61. assert len(in_memory_gateway.data) == 2
  62. async def test_remove_not_existing(in_memory_gateway):
  63. assert not await in_memory_gateway.remove(4)
  64. assert len(in_memory_gateway.data) == 3
  65. async def test_updated_if_unmodified_since(in_memory_gateway):
  66. existing = {"id": 4, "name": "e", "updated_at": datetime.now(timezone.utc)}
  67. new = {"id": 4, "name": "f", "updated_at": datetime.now(timezone.utc)}
  68. await in_memory_gateway.add(existing)
  69. await in_memory_gateway.update(new, if_unmodified_since=existing["updated_at"])
  70. assert in_memory_gateway.data[4]["name"] == "f"
  71. @pytest.mark.parametrize(
  72. "if_unmodified_since", [datetime.now(timezone.utc), datetime(2010, 1, 1)]
  73. )
  74. async def test_update_if_unmodified_since_not_ok(
  75. in_memory_gateway, if_unmodified_since
  76. ):
  77. existing = {"id": 4, "name": "e", "updated_at": datetime.now(timezone.utc)}
  78. new = {"id": 4, "name": "f", "updated_at": datetime.now(timezone.utc)}
  79. await in_memory_gateway.add(existing)
  80. with pytest.raises(Conflict):
  81. await in_memory_gateway.update(new, if_unmodified_since=if_unmodified_since)
  82. async def test_filter_all(in_memory_gateway):
  83. actual = await in_memory_gateway.filter([])
  84. assert actual == sorted(in_memory_gateway.data.values(), key=lambda x: x["id"])
  85. async def test_filter_all_with_params(in_memory_gateway):
  86. actual = await in_memory_gateway.filter(
  87. [], params=PageOptions(limit=2, offset=1, order_by="id", ascending=False)
  88. )
  89. assert [x["id"] for x in actual] == [2, 1]
  90. async def test_filter(in_memory_gateway):
  91. actual = await in_memory_gateway.filter([Filter(field="name", values=["b"])])
  92. assert actual == [in_memory_gateway.data[2]]
  93. async def test_count_all(in_memory_gateway):
  94. actual = await in_memory_gateway.count([])
  95. assert actual == 3
  96. async def test_count_with_filter(in_memory_gateway):
  97. actual = await in_memory_gateway.count([Filter(field="name", values=["b"])])
  98. assert actual == 1
  99. @mock.patch.object(InMemoryGateway, "update")
  100. async def test_update_transactional(update):
  101. record = {"id": 3, "name": "d", "updated_at": datetime(2010, 1, 1)}
  102. gateway = InMemoryGateway([record])
  103. await gateway.update_transactional(3, lambda x: {"name": x["name"] + "x"})
  104. update.assert_awaited_once_with(
  105. {"name": "dx"}, if_unmodified_since=datetime(2010, 1, 1)
  106. )
  107. async def test_update_transactional_does_not_exist(in_memory_gateway):
  108. with pytest.raises(DoesNotExist):
  109. await in_memory_gateway.update_transactional(5, lambda x: x)
  110. async def test_exists_all(in_memory_gateway):
  111. assert await in_memory_gateway.exists([])
  112. async def test_exists_with_filter(in_memory_gateway):
  113. assert await in_memory_gateway.exists([Filter(field="name", values=["b"])])
  114. async def test_exists_with_filter_not(in_memory_gateway):
  115. assert not await in_memory_gateway.exists([Filter(field="name", values=["bb"])])