test_sms.py 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. from datetime import datetime, timedelta, timezone
  2. import uuid
  3. from httpx import AsyncClient
  4. from sqlalchemy import false, select
  5. from sqlalchemy.orm import Session
  6. from app.main import app
  7. from app.models import Project, Sms, Sms
  8. from app.tests.conftest import default_project_id, default_volunteer_id, default_sms_id
  9. async def test_read_list_project_sms(
  10. client: AsyncClient, default_user_headers: dict, default_public_project: Project
  11. ):
  12. response = await client.get(
  13. app.url_path_for("list_project_sms", project_id=default_project_id),
  14. )
  15. assert response.status_code == 401
  16. response = await client.get(
  17. app.url_path_for("list_project_sms", project_id=uuid.uuid4()),
  18. headers=default_user_headers,
  19. )
  20. assert response.status_code == 404
  21. response = await client.get(
  22. app.url_path_for("list_project_sms", project_id="pas un uuid valid"),
  23. headers=default_user_headers,
  24. )
  25. assert response.status_code == 422
  26. response = await client.get(
  27. app.url_path_for("list_project_sms", project_id=default_project_id),
  28. headers=default_user_headers,
  29. )
  30. assert response.status_code == 200
  31. data = response.json()
  32. assert len(data) == 1
  33. assert data[0]["id"] == default_sms_id
  34. async def test_create_sms(
  35. client: AsyncClient,
  36. default_public_project: Project,
  37. default_user_headers: dict,
  38. session: Session,
  39. ):
  40. # Test without autentication
  41. response = await client.post(
  42. app.url_path_for("create_sms", project_id=default_project_id)
  43. )
  44. assert response.status_code == 401
  45. starting_time = datetime(1900, 1, 1)
  46. payload = {"phone_number": "06 75 75 75 75 ", "content": "sms_content"}
  47. # test invalid project_id
  48. response = await client.post(
  49. app.url_path_for("create_sms", project_id=uuid.uuid4()),
  50. json=payload,
  51. headers=default_user_headers,
  52. )
  53. assert response.status_code == 404
  54. # Test normal payload
  55. before_creation_time = datetime.now(timezone.utc)
  56. response = await client.post(
  57. app.url_path_for("create_sms", project_id=default_project_id),
  58. json=payload,
  59. headers=default_user_headers,
  60. )
  61. assert response.status_code == 200
  62. assert response.json()["content"] == "sms_content"
  63. result = session.execute(
  64. select(Sms).where(
  65. (Sms.project_id == default_project_id) & (Sms.id != default_sms_id)
  66. )
  67. )
  68. sms = result.scalars().first()
  69. assert sms is not None
  70. assert sms.content == "sms_content"
  71. assert before_creation_time < sms.sending_time
  72. assert sms.sending_time < datetime.now(timezone.utc)
  73. # test invalid payload
  74. del payload["content"]
  75. response = await client.post(
  76. app.url_path_for("create_sms", project_id=default_project_id),
  77. json=payload,
  78. headers=default_user_headers,
  79. )
  80. assert response.status_code == 422
  81. async def test_update_sms(
  82. client: AsyncClient,
  83. default_public_project: Project,
  84. default_user_headers: dict,
  85. session: Session,
  86. ):
  87. # Test without autentication
  88. response = await client.post(
  89. app.url_path_for(
  90. "update_sms",
  91. project_id=default_project_id,
  92. sms_id=default_sms_id,
  93. )
  94. )
  95. assert response.status_code == 401
  96. # Test invalid payload
  97. response = await client.post(
  98. app.url_path_for(
  99. "update_sms",
  100. project_id=default_project_id,
  101. sms_id=default_sms_id,
  102. ),
  103. json={"volunteer_id": True},
  104. headers=default_user_headers,
  105. )
  106. assert response.status_code == 422
  107. payload = {
  108. "volunteer_id": default_volunteer_id,
  109. "phone_number": "06 75 75 75 75 ",
  110. "content": "sms_content",
  111. "sending_time": datetime(2024, 5, 17, tzinfo=timezone.utc).isoformat(),
  112. }
  113. # test invalid project_id
  114. response = await client.post(
  115. app.url_path_for(
  116. "update_sms",
  117. project_id=uuid.uuid4(),
  118. sms_id=default_sms_id,
  119. ),
  120. json=payload,
  121. headers=default_user_headers,
  122. )
  123. assert response.status_code == 404
  124. # test invalid sms_id
  125. response = await client.post(
  126. app.url_path_for(
  127. "update_sms",
  128. project_id=default_project_id,
  129. sms_id=uuid.uuid4(),
  130. ),
  131. json=payload,
  132. headers=default_user_headers,
  133. )
  134. assert response.status_code == 404
  135. # Test normal payload
  136. for k, v in payload.items():
  137. response = await client.post(
  138. app.url_path_for(
  139. "update_sms",
  140. project_id=default_project_id,
  141. sms_id=default_sms_id,
  142. ),
  143. json={k: v},
  144. headers=default_user_headers,
  145. )
  146. assert response.status_code == 200
  147. assert response.json()["id"] == default_sms_id
  148. if "time" in k:
  149. parsed_time = datetime.fromisoformat(response.json()[k])
  150. assert parsed_time == datetime.fromisoformat(v)
  151. else:
  152. assert response.json()[k] == v
  153. async def test_delete_sms(
  154. client: AsyncClient,
  155. default_user_headers: dict,
  156. session: Session,
  157. default_public_project: Project,
  158. ):
  159. # Fail deleting the project due to not logged in
  160. response = await client.delete(
  161. app.url_path_for(
  162. "delete_sms",
  163. project_id=default_project_id,
  164. sms_id=default_sms_id,
  165. )
  166. )
  167. assert response.status_code == 401
  168. result = session.execute(select(Sms).where(Sms.id == default_sms_id))
  169. sms = result.scalars().first()
  170. assert sms is not None
  171. # Proper deletion
  172. response = await client.delete(
  173. app.url_path_for(
  174. "delete_sms",
  175. project_id=default_project_id,
  176. sms_id=default_sms_id,
  177. ),
  178. headers=default_user_headers,
  179. )
  180. assert response.status_code == 200
  181. result = session.execute(select(Sms).where(Sms.id == default_sms_id))
  182. sms = result.scalars().first()
  183. assert sms is None
  184. # Idempotence test
  185. response = await client.delete(
  186. app.url_path_for(
  187. "delete_sms",
  188. project_id=default_project_id,
  189. sms_id=default_sms_id,
  190. ),
  191. headers=default_user_headers,
  192. )
  193. assert response.status_code == 200
  194. # can delete random uuid
  195. response = await client.delete(
  196. app.url_path_for(
  197. "delete_sms", project_id=default_project_id, sms_id=uuid.uuid4()
  198. ),
  199. headers=default_user_headers,
  200. )
  201. assert response.status_code == 200
  202. # Cannot delete non uuid string
  203. response = await client.delete(
  204. app.url_path_for(
  205. "delete_sms", project_id=default_project_id, sms_id="not uidstr"
  206. ),
  207. headers=default_user_headers,
  208. )
  209. assert response.status_code == 422