label_tests.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. from flask import url_for
  2. from pycs import db
  3. from pycs.database.Label import Label
  4. from pycs.database.Model import Model
  5. from pycs.database.Project import Project
  6. from tests.client.project_tests import _BaseProjectTests
  7. class _BaseLabelTests(_BaseProjectTests):
  8. def setupModels(self):
  9. super().setupModels()
  10. self.project = Project.new(
  11. name="test_project",
  12. description="Project for a test case",
  13. model=self.model,
  14. root_folder="project_folder",
  15. external_data=False,
  16. data_folder="project_folder/data",
  17. )
  18. def tearDown(self):
  19. self.project.delete()
  20. super().tearDown()
  21. class LabelCreationTests(_BaseLabelTests):
  22. def setUp(self):
  23. super().setUp()
  24. self.url = url_for("create_label", project_id=self.project.id)
  25. def test_create_labels(self):
  26. self.assertEqual(0, self.project.labels.count())
  27. self.post(self.url, json=dict(), status_code=400)
  28. self.assertEqual(0, self.project.labels.count())
  29. for i in range(1, 11):
  30. self.post(self.url, json=dict(name=f"Label{i}"))
  31. self.assertEqual(self.project.labels.count(), i)
  32. last_label = Label.query.order_by(Label.id.desc()).first()
  33. self.assertEqual(last_label.name, f"Label{i}")
  34. def test_create_label_with_same_name(self):
  35. self.assertEqual(0, self.project.labels.count())
  36. name = "SameName"
  37. for i in range(1, 11):
  38. self.post(self.url, json=dict(name=name))
  39. self.assertEqual(self.project.labels.count(), i)
  40. last_label = Label.query.order_by(Label.id.desc()).first()
  41. self.assertEqual(last_label.name, name)
  42. def test_create_labels_with_reference(self):
  43. self.assertEqual(0, self.project.labels.count())
  44. for i in range(1, 11):
  45. self.post(self.url, json=dict(name=f"Label{i}", reference=f"label_ref{i}"))
  46. self.assertEqual(self.project.labels.count(), i)
  47. last_label = Label.query.order_by(Label.id.desc()).first()
  48. self.assertEqual(last_label.name, f"Label{i}")
  49. self.assertEqual(last_label.reference, f"label_ref{i}")
  50. def test_create_labels_with_same_reference(self):
  51. self.assertEqual(0, self.project.labels.count())
  52. ref = "same_ref"
  53. self.post(self.url, json=dict(name=f"Label", reference=ref))
  54. last_label = Label.query.order_by(Label.id.desc()).first()
  55. self.assertEqual(last_label.name, f"Label")
  56. self.assertEqual(last_label.reference, ref)
  57. for i in range(2, 11):
  58. self.post(self.url, status_code=400, json=dict(name=f"Label{i}", reference=ref))
  59. self.assertEqual(self.project.labels.count(), 1)
  60. last_label = Label.query.order_by(Label.id.desc()).first()
  61. self.assertEqual(last_label.name, f"Label")
  62. self.assertEqual(last_label.reference, ref)
  63. class LabelListTests(_BaseLabelTests):
  64. def setupModels(self):
  65. super().setupModels()
  66. for i in range(1, 11):
  67. parent, is_new = self.project.create_label(
  68. name=f"Label{i}",
  69. reference=f"label{i}",
  70. hierarchy_level="Level1",
  71. )
  72. self.assertTrue(is_new)
  73. for j in range(1, 4):
  74. label, is_new = self.project.create_label(
  75. name=f"Label{i}_{j}",
  76. reference=f"label{i}_{j}",
  77. hierarchy_level="Level2",
  78. parent=parent)
  79. self.assertTrue(is_new)
  80. for k in range(1, 4):
  81. final_label, is_new = self.project.create_label(
  82. name=f"Label{i}_{j}_{k}",
  83. reference=f"label{i}_{j}_{k}",
  84. parent=label)
  85. self.assertTrue(is_new)
  86. def test_list_labels(self):
  87. self.get(url_for("list_labels", project_id=4242), status_code=404)
  88. response = self.get(url_for("list_labels", project_id=self.project.id))
  89. self.assertTrue(response.is_json)
  90. content = response.json
  91. labels = {l.id: l for l in self.project.labels.all()}
  92. self.assertEqual(len(labels), len(content))
  93. for entry in content:
  94. label = labels[entry["id"]]
  95. self.assertDictEqual(label.serialize(), entry)
  96. def test_list_label_tree(self):
  97. self.get(url_for("list_label_tree", project_id=4242), status_code=404)
  98. response = self.get(url_for("list_label_tree", project_id=self.project.id))
  99. self.assertTrue(response.is_json)
  100. content = response.json
  101. root_labels = {l.id: l for l in Label.query.filter(
  102. Label.project_id==self.project.id, Label.parent_id==None).all()}
  103. self.assertEqual(len(root_labels), len(content))
  104. Label.serialize_only += ("children",)
  105. for entry in content:
  106. label = root_labels[entry["id"]]
  107. self.assertDictEqual(label.serialize(), entry)
  108. class LabelRemovalTests(_BaseLabelTests):
  109. def url(self, label_id):
  110. return url_for("remove_label",
  111. project_id=self.project.id, label_id=label_id)
  112. def setupModels(self):
  113. super().setupModels()
  114. self.N = 10
  115. self.labels = []
  116. with db.session.begin_nested():
  117. for i in range(1, self.N+1):
  118. label, is_new = self.project.create_label(
  119. commit=False,
  120. name=f"Label{i}",
  121. reference=f"Label{i}",
  122. )
  123. assert is_new, "labels should be new"
  124. label.flush()
  125. self.labels.append(label)
  126. def test_remove_label_without_flag(self):
  127. self.assertEqual(self.N, self.project.labels.count())
  128. self.post(self.url(self.labels[0].id), status_code=400)
  129. self.assertEqual(self.N, self.project.labels.count())
  130. self.post(self.url(self.labels[0].id), status_code=400, json=dict(remove=False))
  131. self.assertEqual(self.N, self.project.labels.count())
  132. def test_remove_label(self):
  133. self.assertEqual(self.N, self.project.labels.count())
  134. self.post(self.url(self.labels[0].id), json=dict(remove=True))
  135. self.assertEqual(self.N-1, self.project.labels.count())
  136. def test_remove_non_existing_label(self):
  137. self.assertEqual(self.N, self.project.labels.count())
  138. self.post(self.url(424242), json=dict(remove=True), status_code=404)
  139. self.assertEqual(self.N, self.project.labels.count())
  140. class LabelTreeRemovalTests(_BaseLabelTests):
  141. def url(self, label_id):
  142. return url_for("remove_label",
  143. project_id=self.project.id, label_id=label_id)
  144. def setupModels(self):
  145. super().setupModels()
  146. self.n_roots = 5
  147. self.leafs_per_root = 3
  148. self.n_leafs = self.n_roots * self.leafs_per_root
  149. self.N = self.n_roots + self.n_leafs
  150. with db.session.begin_nested():
  151. for i in range(1, self.n_roots+1):
  152. root_label, is_new = self.project.create_label(
  153. commit=False,
  154. name=f"Label{i}",
  155. reference=f"Label{i}",
  156. )
  157. root_label.flush()
  158. for j in range(1, self.leafs_per_root+1):
  159. label, is_new = self.project.create_label(
  160. commit=False,
  161. name=f"Label{i}_{j}",
  162. reference=f"Label{i}_{j}",
  163. parent=root_label
  164. )
  165. label.flush()
  166. @property
  167. def root_labels(self):
  168. return self.project.labels.filter(Label.parent_id == None)
  169. @property
  170. def leaf_labels(self):
  171. return self.project.labels.filter(Label.parent_id != None)
  172. def test_remove_root_label(self):
  173. self.assertEqual(self.N, self.project.labels.count())
  174. self.assertEqual(self.n_roots, self.root_labels.count())
  175. self.assertEqual(self.n_leafs, self.leaf_labels.count())
  176. label = self.root_labels.first()
  177. self.post(self.url(label.id), json=dict(remove=True))
  178. self.assertEqual(self.N-1, self.project.labels.count())
  179. self.assertEqual(self.n_roots-1+self.leafs_per_root, self.root_labels.count())
  180. self.assertEqual(self.n_leafs-self.leafs_per_root, self.leaf_labels.count())
  181. def test_remove_leaf_label(self):
  182. self.assertEqual(self.N, self.project.labels.count())
  183. self.assertEqual(self.n_roots, self.root_labels.count())
  184. self.assertEqual(self.n_leafs, self.leaf_labels.count())
  185. label = self.leaf_labels.first()
  186. self.post(self.url(label.id), json=dict(remove=True))
  187. self.assertEqual(self.N-1, self.project.labels.count())
  188. self.assertEqual(self.n_roots, self.root_labels.count())
  189. self.assertEqual(self.n_leafs-1, self.leaf_labels.count())
  190. def test_remove_intermediate_label(self):
  191. self.assertEqual(self.N, self.project.labels.count())
  192. self.assertEqual(self.n_roots, self.root_labels.count())
  193. self.assertEqual(self.n_leafs, self.leaf_labels.count())
  194. label = self.leaf_labels.first()
  195. label_parent = label.parent
  196. new_label, is_new = self.project.create_label(
  197. commit=False,
  198. name="New Label",
  199. reference="new_ref",
  200. parent=label,
  201. )
  202. self.assertTrue(is_new)
  203. self.assertEqual(label.id, new_label.parent_id)
  204. self.assertEqual(self.n_roots, self.root_labels.count())
  205. self.assertEqual(self.n_leafs + 1, self.leaf_labels.count())
  206. self.post(self.url(label.id), json=dict(remove=True))
  207. self.assertEqual(label_parent.id, new_label.parent_id)
  208. self.assertEqual(self.n_roots, self.root_labels.count())
  209. self.assertEqual(self.n_leafs, self.leaf_labels.count())
  210. class LabelEditTests(_BaseLabelTests):
  211. def test_edit_name(self):
  212. self.assertEqual(0, self.project.labels.count())
  213. label = self.project.create_label(name="Label", reference="label")
  214. self.assertEqual(1, self.project.labels.count())
  215. label = self.project.labels.first()
  216. self.assertEqual("Label", label.name)
  217. self.post(self.url(label.id), json=dict(), status_code=400)
  218. name = "Another name"
  219. self.post(self.url(label.id), json=dict(name=name))
  220. label = self.project.labels.first()
  221. self.assertEqual(name, label.name)
  222. def test_edit_name(self):
  223. self.assertEqual(0, self.project.labels.count())
  224. label = self.project.create_label(name="Label", reference="label")
  225. self.assertEqual(1, self.project.labels.count())
  226. label = self.project.labels.first()
  227. self.assertEqual("Label", label.name)
  228. url = lambda label_id: url_for("edit_label_name",
  229. project_id=self.project.id, label_id=label_id)
  230. self.post(url(label.id), json=dict(), status_code=400)
  231. name = "Another name"
  232. self.post(url(4242), json=dict(name=name), status_code=404)
  233. self.post(url(label.id), json=dict(name=name))
  234. label = self.project.labels.first()
  235. self.assertEqual(name, label.name)
  236. def test_edit_parent(self):
  237. self.assertEqual(0, self.project.labels.count())
  238. label, _ = self.project.create_label(name="Label", reference="label")
  239. parent, _ = self.project.create_label(name="Label2", reference="label2")
  240. self.assertEqual(2, self.project.labels.count())
  241. label = Label.query.get(label.id)
  242. self.assertIsNone(label.parent_id)
  243. url = lambda label_id: url_for("edit_label_parent",
  244. project_id=self.project.id, label_id=label_id)
  245. self.post(url(label.id), json=dict(), status_code=400)
  246. self.post(url(4242), json=dict(parent=parent.id), status_code=404)
  247. self.post(url(label.id), json=dict(parent=parent.id))
  248. label = Label.query.get(label.id)
  249. self.assertEqual(parent.id, label.parent_id)