test_oa_tasks_pagination.py 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. """OA 待办/已办/我发起/抄送列表分页"""
  2. import unittest
  3. from datetime import datetime, timedelta
  4. from sqlalchemy import create_engine
  5. from sqlalchemy.orm import sessionmaker
  6. class TestListTasksPagination(unittest.TestCase):
  7. def setUp(self):
  8. from app.models.models import OaApp, OaAppVersion, OaInstance, OaTask, SysUser
  9. self.engine = create_engine("sqlite:///:memory:")
  10. OaApp.__table__.create(self.engine)
  11. OaAppVersion.__table__.create(self.engine)
  12. OaInstance.__table__.create(self.engine)
  13. OaTask.__table__.create(self.engine)
  14. SysUser.__table__.create(self.engine)
  15. Session = sessionmaker(bind=self.engine, autoflush=False, autocommit=False)
  16. self.db = Session()
  17. self.OaTask = OaTask
  18. self.OaInstance = OaInstance
  19. now = datetime(2026, 8, 11, 10, 0, 0)
  20. self.db.add(
  21. OaApp(
  22. id="app1",
  23. app_name="请假审批",
  24. initiator_scope="all",
  25. admin_scope="all_oa_admin",
  26. status="1",
  27. tenant_no="zkxw",
  28. create_dept_id="",
  29. create_time=now,
  30. update_time=now,
  31. del_flag=0,
  32. )
  33. )
  34. self.db.add(
  35. OaAppVersion(
  36. id="v1",
  37. app_id="app1",
  38. version_no=1,
  39. status="published",
  40. is_latest_published="1",
  41. form_schema_json="{}",
  42. flow_tree_json="{}",
  43. advanced_settings_json="{}",
  44. tenant_no="zkxw",
  45. create_dept_id="",
  46. create_time=now,
  47. update_time=now,
  48. del_flag=0,
  49. )
  50. )
  51. self.db.add(
  52. SysUser(
  53. id="u0",
  54. user_no="initiator",
  55. nick_name="发起人",
  56. password="x",
  57. tenant_no="zkxw",
  58. create_dept_id="",
  59. create_time=now,
  60. update_time=now,
  61. del_flag=0,
  62. )
  63. )
  64. self.db.add(
  65. SysUser(
  66. id="u1",
  67. user_no="approver",
  68. nick_name="审批人",
  69. password="x",
  70. tenant_no="zkxw",
  71. create_dept_id="",
  72. create_time=now,
  73. update_time=now,
  74. del_flag=0,
  75. )
  76. )
  77. # 25 条 pending 给 u1;各绑独立实例便于 enrich
  78. for i in range(25):
  79. iid = f"i-p-{i:02d}"
  80. t = now + timedelta(minutes=i)
  81. self.db.add(
  82. OaInstance(
  83. id=iid,
  84. app_id="app1",
  85. app_version_id="v1",
  86. title=f"单-{i}",
  87. initiator_user_id="u0",
  88. initiator_dept_id="d1",
  89. form_data_json="{}",
  90. status="running",
  91. tenant_no="zkxw",
  92. create_dept_id="",
  93. create_time=t,
  94. update_time=t,
  95. del_flag=0,
  96. )
  97. )
  98. self.db.add(
  99. OaTask(
  100. id=f"t-p-{i:02d}",
  101. instance_id=iid,
  102. node_key="a1",
  103. node_name="审批",
  104. task_type="approval",
  105. assignee_user_id="u1",
  106. status="pending",
  107. tenant_no="zkxw",
  108. create_dept_id="",
  109. create_time=t,
  110. update_time=t,
  111. del_flag=0,
  112. )
  113. )
  114. # 3 条 mine 实例
  115. for i in range(3):
  116. t = now + timedelta(hours=i)
  117. self.db.add(
  118. OaInstance(
  119. id=f"i-m-{i}",
  120. app_id="app1",
  121. app_version_id="v1",
  122. title=f"我发-{i}",
  123. initiator_user_id="u0",
  124. initiator_dept_id="d1",
  125. form_data_json="{}",
  126. status="running",
  127. tenant_no="zkxw",
  128. create_dept_id="",
  129. create_time=t,
  130. update_time=t,
  131. del_flag=0,
  132. )
  133. )
  134. # 5 条 cc,其中 2 未读
  135. for i in range(5):
  136. iid = f"i-c-{i}"
  137. t = now + timedelta(seconds=i)
  138. self.db.add(
  139. OaInstance(
  140. id=iid,
  141. app_id="app1",
  142. app_version_id="v1",
  143. title=f"抄送-{i}",
  144. initiator_user_id="u0",
  145. initiator_dept_id="d1",
  146. form_data_json="{}",
  147. status="running",
  148. tenant_no="zkxw",
  149. create_dept_id="",
  150. create_time=t,
  151. update_time=t,
  152. del_flag=0,
  153. )
  154. )
  155. self.db.add(
  156. OaTask(
  157. id=f"t-c-{i}",
  158. instance_id=iid,
  159. node_key="cc1",
  160. node_name="抄送",
  161. task_type="cc",
  162. assignee_user_id="u1",
  163. status="done",
  164. is_read=0 if i < 2 else 1,
  165. tenant_no="zkxw",
  166. create_dept_id="",
  167. create_time=t,
  168. update_time=t,
  169. del_flag=0,
  170. )
  171. )
  172. self.db.commit()
  173. def tearDown(self):
  174. self.db.close()
  175. self.engine.dispose()
  176. def test_pending_paginates(self):
  177. from app.services.oa_engine import list_tasks
  178. page1 = list_tasks(
  179. self.db, tenant_no="zkxw", user_id="u1", kind="pending", page=1, page_size=20
  180. )
  181. self.assertEqual(page1["total"], 25)
  182. self.assertEqual(len(page1["list"]), 20)
  183. page2 = list_tasks(
  184. self.db, tenant_no="zkxw", user_id="u1", kind="pending", page=2, page_size=20
  185. )
  186. self.assertEqual(page2["total"], 25)
  187. self.assertEqual(len(page2["list"]), 5)
  188. ids1 = {r["id"] for r in page1["list"]}
  189. ids2 = {r["id"] for r in page2["list"]}
  190. self.assertFalse(ids1 & ids2)
  191. def test_mine_paginates(self):
  192. from app.services.oa_engine import list_tasks
  193. # u0 发起:25 pending 实例 + 3 mine + 5 cc 实例 = 33
  194. res = list_tasks(
  195. self.db, tenant_no="zkxw", user_id="u0", kind="mine", page=1, page_size=10
  196. )
  197. self.assertEqual(res["total"], 33)
  198. self.assertEqual(len(res["list"]), 10)
  199. def test_cc_unread_filter_then_paginate(self):
  200. from app.services.oa_engine import list_tasks
  201. res = list_tasks(
  202. self.db,
  203. tenant_no="zkxw",
  204. user_id="u1",
  205. kind="cc",
  206. read_status="unread",
  207. page=1,
  208. page_size=20,
  209. )
  210. self.assertEqual(res["total"], 2)
  211. self.assertEqual(len(res["list"]), 2)
  212. self.assertTrue(all(not r.get("isRead") for r in res["list"]))
  213. if __name__ == "__main__":
  214. unittest.main()