test_project.py 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. import uuid
  2. from httpx import AsyncClient
  3. from sqlalchemy import select
  4. from sqlalchemy.orm import Session
  5. from app.main import app
  6. from app.models import Project, Slot, Sms, Volunteer
  7. from app.tests.conftest import default_project_id, default_project_name, default_sms_id
  8. async def test_read_list_project(
  9. client: AsyncClient, default_user_headers: dict, default_project: Project
  10. ):
  11. response = await client.get(
  12. app.url_path_for("list_project"), headers=default_user_headers
  13. )
  14. assert response.status_code == 200
  15. data = response.json()
  16. assert len(data) == 1
  17. project_response = data[0]
  18. assert project_response["id"] == default_project_id
  19. assert "created_at" in project_response
  20. async def test_read_list_project_without_user(client: AsyncClient):
  21. response = await client.get(app.url_path_for("list_project"))
  22. assert response.status_code == 401
  23. async def test_read_list_public_project_without_user(
  24. client: AsyncClient, default_project: Project
  25. ):
  26. response = await client.get(app.url_path_for("list_public_project"))
  27. assert response.status_code == 200
  28. data = response.json()
  29. assert len(data) == 0
  30. async def test_read_list_public_project_without_user_1(
  31. client: AsyncClient, default_public_project: Project
  32. ):
  33. response = await client.get(app.url_path_for("list_public_project"))
  34. assert response.status_code == 200
  35. data = response.json()
  36. assert len(data) == 1
  37. async def test_get_project_without_user(client: AsyncClient, default_project: Project):
  38. response = await client.get(
  39. app.url_path_for("get_public_project", project_id=default_project_id)
  40. )
  41. assert response.status_code == 404
  42. async def test_get_public_project(client: AsyncClient, default_public_project: Project):
  43. response = await client.get(
  44. app.url_path_for("get_public_project", project_id=default_project_id)
  45. )
  46. assert response.status_code == 200
  47. assert response.json()["id"] == default_project_id
  48. assert response.json()["name"] == default_project_name
  49. async def test_get_project(
  50. client: AsyncClient, default_public_project: Project, default_user_headers: dict
  51. ):
  52. # Test without autentication
  53. response = await client.get(
  54. app.url_path_for("get_project", project_id=default_project_id)
  55. )
  56. assert response.status_code == 401
  57. response = await client.get(
  58. app.url_path_for("get_project", project_id=default_project_id),
  59. headers=default_user_headers,
  60. )
  61. assert response.status_code == 200
  62. assert response.json()["id"] == default_project_id
  63. assert response.json()["name"] == default_project_name
  64. async def test_create_project_without_user(client: AsyncClient, session: Session):
  65. response = await client.post(
  66. app.url_path_for("create_project"),
  67. json={"name": "Coucou"},
  68. )
  69. assert response.status_code == 401
  70. # Verify no project were added
  71. result = session.execute(select(Project))
  72. project = result.scalars().first()
  73. assert project is None
  74. async def test_create_project(
  75. client: AsyncClient, default_user_headers: dict, session: Session
  76. ):
  77. # Create a private project
  78. response = await client.post(
  79. app.url_path_for("create_project"),
  80. headers=default_user_headers,
  81. json={"name": "Coucou"},
  82. )
  83. assert response.status_code == 200
  84. result = session.execute(select(Project).where(Project.name == "Coucou"))
  85. project = result.scalars().first()
  86. assert project is not None
  87. assert project.is_public == False
  88. # Create a public project
  89. response = await client.post(
  90. app.url_path_for("create_project"),
  91. headers=default_user_headers,
  92. json={"name": "Public", "is_public": True},
  93. )
  94. assert response.status_code == 200
  95. result = session.execute(select(Project).where(Project.name == "Public"))
  96. project = result.scalars().first()
  97. assert project is not None
  98. assert project.is_public
  99. async def test_create_project_fail(
  100. client: AsyncClient, default_user_headers: dict, session: Session
  101. ):
  102. # Create a project with a bad
  103. response = await client.post(
  104. app.url_path_for("create_project"),
  105. headers=default_user_headers,
  106. json={"coucou": "Coucou"},
  107. )
  108. assert response.status_code == 422
  109. assert "detail" in response.json()
  110. result = session.execute(select(Project))
  111. project = result.scalars().first()
  112. assert project is None
  113. async def test_update_project(
  114. client: AsyncClient,
  115. default_user_headers: dict,
  116. session: Session,
  117. default_public_project: Project,
  118. ):
  119. # Update a public project
  120. response = await client.post(
  121. app.url_path_for("update_project", project_id=default_project_id),
  122. headers=default_user_headers,
  123. json={"name": "Coucou"},
  124. )
  125. assert response.status_code == 200
  126. result = session.execute(select(Project).where(Project.id == default_project_id))
  127. project = result.scalars().first()
  128. assert project is not None
  129. assert project.name == "Coucou"
  130. # Update a public project
  131. response = await client.post(
  132. app.url_path_for("update_project", project_id=default_project_id),
  133. headers=default_user_headers,
  134. json={"name": "Coucou 2", "is_public": False},
  135. )
  136. assert response.status_code == 200
  137. session.refresh(project)
  138. assert project is not None
  139. assert project.name == "Coucou 2"
  140. assert project.created_at < project.updated_at
  141. assert not project.is_public
  142. async def test_update_project_fail(
  143. client: AsyncClient,
  144. default_user_headers: dict,
  145. session: Session,
  146. default_public_project: Project,
  147. ):
  148. # Fail updating the project due to not logged in
  149. response = await client.post(
  150. app.url_path_for("update_project", project_id=default_project_id),
  151. json={"name": "Coucou 2"},
  152. )
  153. assert response.status_code == 401
  154. result = session.execute(select(Project).where(Project.id == default_project_id))
  155. project = result.scalars().first()
  156. assert project is not None
  157. assert project.name == default_project_name
  158. # Update is_public without name => Validation error
  159. response = await client.post(
  160. app.url_path_for("update_project", project_id=default_project_id),
  161. headers=default_user_headers,
  162. json={"is_public": False},
  163. )
  164. assert response.status_code == 422
  165. async def test_create_sms_batch(
  166. client: AsyncClient,
  167. default_user_headers: dict,
  168. session: Session,
  169. default_public_project: Project,
  170. ):
  171. #
  172. response = await client.post(
  173. app.url_path_for("create_sms_batch", project_id=default_project_id),
  174. json={"is_public": False},
  175. )
  176. assert response.status_code == 401
  177. # créer un sms simple
  178. response = await client.post(
  179. app.url_path_for("create_sms_batch", project_id=default_project_id),
  180. headers=default_user_headers,
  181. json={"template": "Bonjour {prenom}!\n{titre}"},
  182. )
  183. assert response.status_code == 200
  184. result = session.execute(
  185. select(Sms).where(
  186. (Sms.project_id == default_project_id) & (Sms.id != default_sms_id)
  187. )
  188. )
  189. sms = result.scalars().first()
  190. assert sms is not None
  191. assert sms.content == "Bonjour Arthur!\nêtre roi"
  192. async def test_delete_project(
  193. client: AsyncClient,
  194. default_user_headers: dict,
  195. session: Session,
  196. default_public_project: Project,
  197. ):
  198. # Fail deleting the project due to not logged in
  199. response = await client.delete(
  200. app.url_path_for("delete_project", project_id=default_project_id)
  201. )
  202. assert response.status_code == 401
  203. result = session.execute(select(Project).where(Project.id == default_project_id))
  204. project = result.scalars().first()
  205. assert project is not None
  206. # Proper deletion
  207. response = await client.delete(
  208. app.url_path_for("delete_project", project_id=default_project_id),
  209. headers=default_user_headers,
  210. )
  211. assert response.status_code == 200
  212. result = session.execute(select(Project).where(Project.id == default_project_id))
  213. project = result.scalars().first()
  214. assert project is None
  215. # check deletion is cascaded to volunteers
  216. result = session.execute(
  217. select(Volunteer).where(Volunteer.project_id == default_project_id)
  218. )
  219. volunteer = result.scalars().first()
  220. assert volunteer is None
  221. # check deletion is cascaded to slots
  222. result = session.execute(select(Slot).where(Slot.project_id == default_project_id))
  223. slot = result.scalars().first()
  224. assert slot is None
  225. # Idempotence test
  226. response = await client.delete(
  227. app.url_path_for("delete_project", project_id=default_project_id),
  228. headers=default_user_headers,
  229. )
  230. assert response.status_code == 200
  231. # can delete random uuid
  232. response = await client.delete(
  233. app.url_path_for("delete_project", project_id=uuid.uuid4()),
  234. headers=default_user_headers,
  235. )
  236. assert response.status_code == 200
  237. # Cannot delete non uuid string
  238. response = await client.delete(
  239. app.url_path_for("delete_project", project_id="not uidstr"),
  240. headers=default_user_headers,
  241. )
  242. assert response.status_code == 422