Add approval instance drafts with menu badges, dual-track user/role read model and role bound names, form-designer outline docs, and bare-metal test deploy scripts. Ignore local test-server credential file. Co-authored-by: Cursor <cursoragent@cursor.com>
55 lines
1.8 KiB
Python
55 lines
1.8 KiB
Python
"""OA 发起审批草稿序列化与访问错误"""
|
|
import unittest
|
|
from datetime import datetime
|
|
from types import SimpleNamespace
|
|
|
|
from app.crud.oa_instance_draft import DraftAccessError, row_to_dict
|
|
|
|
|
|
class TestOaInstanceDraftRowToDict(unittest.TestCase):
|
|
def _row(self, **kwargs):
|
|
base = dict(
|
|
id="d1",
|
|
app_id="a1",
|
|
app_version_id="v1",
|
|
title="请假",
|
|
form_data_json='{"days":1}',
|
|
initiator_select_json='{"n1":["u1"]}',
|
|
initiator_dept_id="dept1",
|
|
owner_user_id="u-owner",
|
|
create_time=datetime(2026, 8, 6, 10, 0, 0),
|
|
update_time=datetime(2026, 8, 6, 11, 0, 0),
|
|
)
|
|
base.update(kwargs)
|
|
return SimpleNamespace(**base)
|
|
|
|
def test_list_shape_without_payload(self):
|
|
d = row_to_dict(
|
|
self._row(),
|
|
app_name="请假申请",
|
|
version_no=3,
|
|
group_id="g1",
|
|
group_name="人事",
|
|
)
|
|
self.assertEqual(d["id"], "d1")
|
|
self.assertEqual(d["appId"], "a1")
|
|
self.assertEqual(d["appName"], "请假申请")
|
|
self.assertEqual(d["versionNo"], 3)
|
|
self.assertEqual(d["status"], "draft")
|
|
self.assertEqual(d["updateTime"], "2026-08-06 11:00:00")
|
|
self.assertNotIn("formData", d)
|
|
|
|
def test_detail_includes_payload(self):
|
|
d = row_to_dict(self._row(), include_payload=True)
|
|
self.assertEqual(d["formData"], {"days": 1})
|
|
self.assertEqual(d["initiatorSelectByNode"], {"n1": ["u1"]})
|
|
self.assertEqual(d["initiatorDeptId"], "dept1")
|
|
|
|
def test_access_error_message(self):
|
|
err = DraftAccessError("草稿不存在或无权访问")
|
|
self.assertEqual(str(err), "草稿不存在或无权访问")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|