test_template.py 8.4 KB

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