test_template.py 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. from uuid import uuid4
  2. from httpx import AsyncClient
  3. import pytest
  4. from sqlalchemy import select
  5. from sqlalchemy.orm import Session
  6. from app.main import app
  7. from app.models import Project, Slot, SlotTemplate
  8. from app.tests.conftest import default_slot_id, default_template_id, default_tag_id
  9. async def test_create_template_fail(
  10. client: AsyncClient,
  11. default_user_headers: dict,
  12. session: Session,
  13. default_public_project: Project,
  14. ):
  15. url = app.url_path_for("create_template", project_id=default_public_project.id)
  16. response = await client.post(url, json={"title": "1st template"})
  17. assert response.status_code == 401
  18. response = await client.post(url, json={}, headers=default_user_headers)
  19. assert response.status_code == 422
  20. url = app.url_path_for("create_template", project_id=uuid4())
  21. response = await client.post(
  22. url, json={"title": "1st template"}, headers=default_user_headers
  23. )
  24. assert response.status_code == 404
  25. @pytest.mark.parametrize(
  26. "payload",
  27. [
  28. {"title": "1st template"},
  29. {"title": "1𝖘ҭ ṥ٥ι𝙪𝓉ìóη", "place": "echo"},
  30. {"title": "1st template", "responsible_contact": "echo"},
  31. {"title": "1st template", "description": "&é'(-è_çecho"},
  32. {"title": "1st template", "place": "3", "description": "&é'(-è_çecho"},
  33. ],
  34. )
  35. async def test_create_template(
  36. client: AsyncClient,
  37. default_user_headers: dict,
  38. session: Session,
  39. default_public_project: Project,
  40. payload: dict,
  41. ):
  42. url = app.url_path_for("create_template", project_id=default_public_project.id)
  43. response = await client.post(url, json=payload, headers=default_user_headers)
  44. assert response.status_code == 200
  45. template = session.get(SlotTemplate, response.json()["id"])
  46. assert template is not None
  47. for k in ["title", "description", "place", "responsible_contact"]:
  48. val = template.__getattribute__(k)
  49. if k in payload:
  50. assert val == payload[k]
  51. else:
  52. assert val == ""
  53. async def test_update_template_fail(
  54. client: AsyncClient,
  55. default_user_headers: dict,
  56. session: Session,
  57. default_public_project: Project,
  58. ):
  59. payload = {"title": "1st template"}
  60. project = session.get(Project, default_public_project.id)
  61. assert project is not None
  62. template_id = project.templates[0].id
  63. url = app.url_path_for(
  64. "update_template", project_id=default_public_project.id, template_id="12"
  65. )
  66. response = await client.post(url, json=payload)
  67. assert response.status_code == 401
  68. response = await client.post(url, json=payload, headers=default_user_headers)
  69. assert response.status_code == 422
  70. url = app.url_path_for(
  71. "update_template", project_id=default_public_project.id, template_id=uuid4()
  72. )
  73. response = await client.post(url, json=payload, headers=default_user_headers)
  74. assert response.status_code == 404
  75. url = app.url_path_for(
  76. "update_template", project_id=uuid4(), template_id=template_id
  77. )
  78. response = await client.post(url, json=payload, headers=default_user_headers)
  79. assert response.status_code == 404
  80. @pytest.mark.parametrize(
  81. "code,payload",
  82. [
  83. (422, {"title": [1.001, 2]}),
  84. (422, {"responsible_contact": {"t": None}}),
  85. (422, {"place": [1, 2]}),
  86. (422, {"tags": ["1", "2"]}),
  87. # (422, {"slots": "1"}),
  88. (400, {"tags": [default_slot_id]}),
  89. ],
  90. )
  91. async def test_update_template_fail_payload_validation(
  92. client: AsyncClient,
  93. default_user_headers: dict,
  94. session: Session,
  95. default_public_project: Project,
  96. payload: dict,
  97. code: int,
  98. ):
  99. url = app.url_path_for(
  100. "update_template",
  101. project_id=default_public_project.id,
  102. template_id=default_template_id,
  103. )
  104. response = await client.post(url, json=payload, headers=default_user_headers)
  105. assert response.status_code == code
  106. @pytest.mark.parametrize(
  107. "payload",
  108. [
  109. {"title": "1st template"},
  110. {"title": "1st template", "place": "echo"},
  111. {"title": "1st template", "responsible_contact": "echo"},
  112. {"title": "1st template", "description": "&é'(-è_çecho"},
  113. {
  114. "title": "1st template",
  115. "place": "Ḽơᶉëᶆ ȋṕšᶙṁ",
  116. "description": "&é'(-è_çecho",
  117. },
  118. {"title": "1st template", "place": "3", "description": "&é'(-è_çecho"},
  119. ],
  120. )
  121. async def test_update_template(
  122. client: AsyncClient,
  123. default_user_headers: dict,
  124. session: Session,
  125. default_public_project: Project,
  126. payload: dict,
  127. ):
  128. url = app.url_path_for(
  129. "update_template",
  130. project_id=default_public_project.id,
  131. template_id=default_template_id,
  132. )
  133. response = await client.post(url, json=payload, headers=default_user_headers)
  134. assert response.status_code == 200
  135. template = session.get(SlotTemplate, default_template_id)
  136. assert template is not None
  137. for k in ["title", "description", "place", "responsible_contact"]:
  138. val = template.__getattribute__(k)
  139. if k in payload:
  140. assert val == payload[k]
  141. else:
  142. assert val == ""
  143. async def test_update_template_lists(
  144. client: AsyncClient,
  145. default_user_headers: dict,
  146. session: Session,
  147. default_public_project: Project,
  148. ):
  149. url = app.url_path_for(
  150. "update_template",
  151. project_id=default_public_project.id,
  152. template_id=default_template_id,
  153. )
  154. payload = {"tags": [default_tag_id]}
  155. response = await client.post(url, json=payload, headers=default_user_headers)
  156. assert response.status_code == 200
  157. template = session.get(SlotTemplate, default_template_id)
  158. assert template is not None
  159. assert len(template.tags) == 1
  160. assert template.tags[0].id == default_tag_id
  161. response = await client.post(url, json={"tags": []}, headers=default_user_headers)
  162. assert response.status_code == 200
  163. session.refresh(template)
  164. assert len(template.tags) == 0
  165. async def test_delete_template_fail(
  166. client: AsyncClient,
  167. default_user_headers: dict,
  168. session: Session,
  169. default_public_project: Project,
  170. ):
  171. # Proper deletion
  172. project_id = default_public_project.id
  173. # no authent
  174. url = app.url_path_for(
  175. "delete_template", project_id=project_id, template_id=default_template_id
  176. )
  177. response = await client.delete(url)
  178. assert response.status_code == 401
  179. # invalid tag
  180. url = app.url_path_for(
  181. "delete_template", project_id=project_id, template_id="default_tag_id"
  182. )
  183. response = await client.delete(url, headers=default_user_headers)
  184. assert response.status_code == 422
  185. # invalid project_id
  186. url = app.url_path_for(
  187. "delete_template", project_id="ded", template_id=default_template_id
  188. )
  189. response = await client.delete(url, headers=default_user_headers)
  190. assert response.status_code == 422
  191. async def test_delete_template(
  192. client: AsyncClient,
  193. default_user_headers: dict,
  194. session: Session,
  195. default_public_project: Project,
  196. ):
  197. # Proper deletion
  198. url = app.url_path_for(
  199. "delete_template",
  200. project_id=default_public_project.id,
  201. template_id=default_template_id,
  202. )
  203. response = await client.delete(url, headers=default_user_headers)
  204. assert response.status_code == 200
  205. result = session.execute(
  206. select(SlotTemplate).where(SlotTemplate.id == default_tag_id)
  207. )
  208. slot = result.scalars().first()
  209. assert slot is None
  210. # can delete random uuid
  211. url = app.url_path_for(
  212. "delete_tag", project_id=default_public_project.id, tag_id=uuid4()
  213. )
  214. response = await client.delete(url, headers=default_user_headers)
  215. assert response.status_code == 200
  216. async def test_delete_template_not_slot(
  217. client: AsyncClient,
  218. default_user_headers: dict,
  219. session: Session,
  220. default_public_project: Project,
  221. ):
  222. # Proper deletion
  223. url = app.url_path_for(
  224. "delete_template",
  225. project_id=default_public_project.id,
  226. template_id=default_template_id,
  227. )
  228. slot = session.get(Slot, default_slot_id)
  229. assert slot is not None
  230. slot.template_id = default_template_id
  231. session.commit()
  232. response = await client.delete(url, headers=default_user_headers)
  233. assert response.status_code == 200
  234. slot = session.get(Slot, default_slot_id)
  235. assert slot is not None