| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- """OA 微信服务号通知钩子单测。"""
- from unittest.mock import MagicMock, patch
- from app.services.oa_wechat_notify import (
- _build_matter_title,
- _send_one,
- build_oa_detail_pagepath,
- )
- def test_build_pagepath_no_leading_slash():
- p = build_oa_detail_pagepath(instance_id="i1", task_id="t1", mode="approve")
- assert p.startswith("pages/")
- assert "mode=approve" in p
- assert "instanceId=i1" in p
- assert "taskId=t1" in p
- def test_build_pagepath_three_notify_targets():
- """三种通知:审批待办 / 抄送查看 / 我发起查看,mode + returnPath 不同。"""
- from urllib.parse import parse_qs, urlparse
- from app.services.oa_wechat_notify import (
- RETURN_CC,
- RETURN_MINE,
- RETURN_PENDING,
- )
- appr = build_oa_detail_pagepath(
- instance_id="i1",
- task_id="t1",
- mode="approve",
- return_path=RETURN_PENDING,
- )
- q1 = parse_qs(urlparse("x://" + appr).query)
- assert q1["mode"] == ["approve"]
- assert q1["taskId"] == ["t1"]
- assert q1["returnPath"] == [RETURN_PENDING]
- cc = build_oa_detail_pagepath(
- instance_id="i1",
- task_id="t-cc",
- mode="view",
- return_path=RETURN_CC,
- )
- q2 = parse_qs(urlparse("x://" + cc).query)
- assert q2["mode"] == ["view"]
- assert q2["taskId"] == ["t-cc"]
- assert q2["returnPath"] == [RETURN_CC]
- mine = build_oa_detail_pagepath(
- instance_id="i1",
- task_id="",
- mode="view",
- return_path=RETURN_MINE,
- )
- q3 = parse_qs(urlparse("x://" + mine).query)
- assert q3["mode"] == ["view"]
- assert "taskId" not in q3
- assert q3["returnPath"] == [RETURN_MINE]
- def test_build_matter_title_applicant_process():
- assert _build_matter_title(
- applicant="李四", process_name="请假申请", fallback="x"
- ) == "李四 - 请假申请"
- assert _build_matter_title(applicant="", process_name="请假申请", fallback="x") == (
- "请假申请"
- )
- assert _build_matter_title(applicant="", process_name="", fallback="审批") == "审批"
- def test_send_one_routes_approval_vs_cc():
- db = MagicMock()
- user = MagicMock()
- user.wx_mp_openid = "mp-openid-1"
- user.nick_name = "张三"
- inst = MagicMock()
- inst.title = "请假"
- inst.initiator_user_id = "u-ini"
- inst.app_id = "app-1"
- ini = MagicMock()
- ini.nick_name = "李四"
- app = MagicMock()
- app.app_name = "请假申请"
- # approval + cc 各查 assignee、initiator
- user_results = [user, ini, user, ini]
- def query_side_effect(model):
- q = MagicMock()
- name = getattr(model, "__name__", "") or str(model)
- if "SysUser" in name:
- q.filter.return_value.first.side_effect = lambda: user_results.pop(0)
- elif "OaApp" in name:
- q.filter.return_value.first.return_value = app
- else:
- q.filter.return_value.first.return_value = inst
- return q
- db.query.side_effect = query_side_effect
- approval_task = MagicMock()
- approval_task.id = "t-appr"
- approval_task.instance_id = "i1"
- approval_task.assignee_user_id = "u1"
- approval_task.task_type = "approval"
- approval_task.status = "pending"
- approval_task.node_name = "主管审批"
- with patch(
- "app.services.oa_wechat_notify.send_oa_approval_notify"
- ) as send_appr, patch(
- "app.services.oa_wechat_notify.send_oa_cc_notify"
- ) as send_cc:
- _send_one(db, approval_task)
- send_appr.assert_called_once()
- send_cc.assert_not_called()
- kwargs = send_appr.call_args.kwargs
- assert kwargs["mp_openid"] == "mp-openid-1"
- assert "mode=approve" in kwargs["pagepath"]
- assert "returnPath=" in kwargs["pagepath"]
- assert "%2Fpages%2Foa%2Fpending%2Findex" in kwargs["pagepath"] or (
- "/pages/oa/pending/index" in kwargs["pagepath"]
- )
- assert kwargs["title"] == "李四 - 请假申请"
- assert kwargs["applicant"] == "李四"
- assert kwargs["process_name"] == "请假申请"
- assert kwargs["node_name"] == "主管审批"
- cc_task = MagicMock()
- cc_task.id = "t-cc"
- cc_task.instance_id = "i1"
- cc_task.assignee_user_id = "u1"
- cc_task.task_type = "cc"
- cc_task.status = "done"
- cc_task.node_name = "抄送"
- with patch(
- "app.services.oa_wechat_notify.send_oa_approval_notify"
- ) as send_appr, patch(
- "app.services.oa_wechat_notify.send_oa_cc_notify"
- ) as send_cc:
- _send_one(db, cc_task)
- send_cc.assert_called_once()
- send_appr.assert_not_called()
- kwargs = send_cc.call_args.kwargs
- assert "mode=view" in kwargs["pagepath"]
- assert (
- "%2Fpages%2Foa%2Fcc%2Findex" in kwargs["pagepath"]
- or "/pages/oa/cc/index" in kwargs["pagepath"]
- )
- assert kwargs["title"] == "李四 - 请假申请"
- assert kwargs["process_name"] == "请假申请"
- def test_schedule_oa_task_notifies_noop_when_disabled():
- with patch("app.services.oa_wechat_notify.settings") as st, patch(
- "app.services.oa_wechat_notify.threading.Thread"
- ) as th:
- st.WX_MP_NOTIFY_ENABLED = False
- from app.services.oa_wechat_notify import schedule_oa_task_notifies
- schedule_oa_task_notifies(["t1"])
- th.assert_not_called()
- def test_schedule_oa_applicant_progress_noop_when_disabled():
- with patch("app.services.oa_wechat_notify.settings") as st, patch(
- "app.services.oa_wechat_notify.threading.Thread"
- ) as th:
- st.WX_MP_NOTIFY_ENABLED = False
- from app.services.oa_wechat_notify import schedule_oa_applicant_progress
- schedule_oa_applicant_progress(
- instance_id="i1", actor_user_id="u1", action="approve"
- )
- th.assert_not_called()
- def test_notify_oa_tasks_sync_noop_when_disabled():
- with patch("app.services.oa_wechat_notify.settings") as st, patch(
- "app.services.oa_wechat_notify.SessionLocal"
- ) as session_local:
- st.WX_MP_NOTIFY_ENABLED = False
- from app.services.oa_wechat_notify import notify_oa_tasks_sync
- notify_oa_tasks_sync(["t1"])
- session_local.assert_not_called()
|