test_project.py 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  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, Volunteer
  7. from app.tests.conftest import default_project_id, default_project_name
  8. async def test_read_list_project(
  9. client: AsyncClient, default_user_headers: dict, default_project: Project
  10. ):
  11. response = await client.get(app.url_path_for("list_project"), headers=default_user_headers)
  12. assert response.status_code == 200
  13. data = response.json()
  14. assert len(data) == 1
  15. project_response = data[0]
  16. assert project_response["id"] == default_project_id
  17. assert "created_at" in project_response
  18. async def test_read_list_project_without_user(client: AsyncClient):
  19. response = await client.get(app.url_path_for("list_project"))
  20. assert response.status_code == 401
  21. async def test_read_list_public_project_without_user(client: AsyncClient, default_project: Project):
  22. response = await client.get(app.url_path_for("list_public_project"))
  23. assert response.status_code == 200
  24. data = response.json()
  25. assert len(data) == 0
  26. async def test_read_list_public_project_without_user_1(
  27. client: AsyncClient, default_public_project: Project
  28. ):
  29. response = await client.get(app.url_path_for("list_public_project"))
  30. assert response.status_code == 200
  31. data = response.json()
  32. assert len(data) == 1
  33. async def test_get_project_without_user(client: AsyncClient, default_project: Project):
  34. response = await client.get(
  35. app.url_path_for("get_public_project", project_id=default_project_id)
  36. )
  37. assert response.status_code == 404
  38. async def test_get_public_project(client: AsyncClient, default_public_project: Project):
  39. response = await client.get(
  40. app.url_path_for("get_public_project", project_id=default_project_id)
  41. )
  42. assert response.status_code == 200
  43. assert response.json()["id"] == default_project_id
  44. assert response.json()["name"] == default_project_name
  45. async def test_get_project(
  46. client: AsyncClient, default_public_project: Project, default_user_headers: dict
  47. ):
  48. # Test without autentication
  49. response = await client.get(app.url_path_for("get_project", project_id=default_project_id))
  50. assert response.status_code == 401
  51. response = await client.get(
  52. app.url_path_for("get_project", project_id=default_project_id),
  53. headers=default_user_headers,
  54. )
  55. assert response.status_code == 200
  56. assert response.json()["id"] == default_project_id
  57. assert response.json()["name"] == default_project_name
  58. async def test_create_project_without_user(client: AsyncClient, session: Session):
  59. response = await client.post(
  60. app.url_path_for("create_project"),
  61. json={"name": "Coucou"},
  62. )
  63. assert response.status_code == 401
  64. # Verify no project were added
  65. result = session.execute(select(Project))
  66. project = result.scalars().first()
  67. assert project is None
  68. async def test_create_project(client: AsyncClient, default_user_headers: dict, session: Session):
  69. # Create a private project
  70. response = await client.post(
  71. app.url_path_for("create_project"),
  72. headers=default_user_headers,
  73. json={"name": "Coucou"},
  74. )
  75. assert response.status_code == 200
  76. result = session.execute(select(Project).where(Project.name == "Coucou"))
  77. project = result.scalars().first()
  78. assert project is not None
  79. assert not project.is_public
  80. # Create a public project
  81. response = await client.post(
  82. app.url_path_for("create_project"),
  83. headers=default_user_headers,
  84. json={"name": "Public", "is_public": True},
  85. )
  86. assert response.status_code == 200
  87. result = session.execute(select(Project).where(Project.name == "Public"))
  88. project = result.scalars().first()
  89. assert project is not None
  90. assert project.is_public
  91. async def test_create_project_fail(
  92. client: AsyncClient, default_user_headers: dict, session: Session
  93. ):
  94. # Create a project with a bad
  95. response = await client.post(
  96. app.url_path_for("create_project"),
  97. headers=default_user_headers,
  98. json={"coucou": "Coucou"},
  99. )
  100. assert response.status_code == 422
  101. assert "detail" in response.json()
  102. result = session.execute(select(Project))
  103. project = result.scalars().first()
  104. assert project is None
  105. async def test_update_project(
  106. client: AsyncClient,
  107. default_user_headers: dict,
  108. session: Session,
  109. default_public_project: Project,
  110. ):
  111. # Update a public project
  112. response = await client.post(
  113. app.url_path_for("update_project", project_id=default_project_id),
  114. headers=default_user_headers,
  115. json={"name": "Coucou"},
  116. )
  117. assert response.status_code == 200
  118. result = session.execute(select(Project).where(Project.id == default_project_id))
  119. project = result.scalars().first()
  120. assert project is not None
  121. assert project.name == "Coucou"
  122. # Update a public project
  123. response = await client.post(
  124. app.url_path_for("update_project", project_id=default_project_id),
  125. headers=default_user_headers,
  126. json={"name": "Coucou 2", "is_public": False},
  127. )
  128. assert response.status_code == 200
  129. session.refresh(project)
  130. assert project is not None
  131. assert project.name == "Coucou 2"
  132. assert project.created_at < project.updated_at
  133. assert not project.is_public
  134. async def test_update_project_fail(
  135. client: AsyncClient,
  136. default_user_headers: dict,
  137. session: Session,
  138. default_public_project: Project,
  139. ):
  140. # Fail updating the project due to not logged in
  141. response = await client.post(
  142. app.url_path_for("update_project", project_id=default_project_id),
  143. json={"name": "Coucou 2"},
  144. )
  145. assert response.status_code == 401
  146. result = session.execute(select(Project).where(Project.id == default_project_id))
  147. project = result.scalars().first()
  148. assert project is not None
  149. assert project.name == default_project_name
  150. # Update is_public without name => Validation error
  151. response = await client.post(
  152. app.url_path_for("update_project", project_id=default_project_id),
  153. headers=default_user_headers,
  154. json={"is_public": False},
  155. )
  156. assert response.status_code == 422
  157. async def test_delete_project(
  158. client: AsyncClient,
  159. default_user_headers: dict,
  160. session: Session,
  161. default_public_project: Project,
  162. ):
  163. # Fail deleting the project due to not logged in
  164. response = await client.delete(
  165. app.url_path_for("delete_project", project_id=default_project_id)
  166. )
  167. assert response.status_code == 401
  168. result = session.execute(select(Project).where(Project.id == default_project_id))
  169. project = result.scalars().first()
  170. assert project is not None
  171. # Proper deletion
  172. response = await client.delete(
  173. app.url_path_for("delete_project", project_id=default_project_id),
  174. headers=default_user_headers,
  175. )
  176. assert response.status_code == 200
  177. result = session.execute(select(Project).where(Project.id == default_project_id))
  178. project = result.scalars().first()
  179. assert project is None
  180. # check deletion is cascaded to volunteers
  181. result = session.execute(select(Volunteer).where(Volunteer.project_id == default_project_id))
  182. volunteer = result.scalars().first()
  183. assert volunteer is None
  184. # check deletion is cascaded to slots
  185. result = session.execute(select(Slot).where(Slot.project_id == default_project_id))
  186. slot = result.scalars().first()
  187. assert slot is None
  188. # Idempotence test
  189. response = await client.delete(
  190. app.url_path_for("delete_project", project_id=default_project_id),
  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("delete_project", project_id=uuid.uuid4()),
  197. headers=default_user_headers,
  198. )
  199. assert response.status_code == 200
  200. # Cannot delete non uuid string
  201. response = await client.delete(
  202. app.url_path_for("delete_project", project_id="not uidstr"),
  203. headers=default_user_headers,
  204. )
  205. assert response.status_code == 422