2026-05-12 00:56:47 +08:00
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
import pytest
|
|
|
|
|
|
|
|
|
|
from yuxi.channels.adapters.wechat.errors import (
|
|
|
|
|
is_token_expired,
|
|
|
|
|
parse_mp_error,
|
|
|
|
|
parse_wecom_error,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
2026-05-13 16:43:01 +08:00
|
|
|
class TestParseWeComError:
|
|
|
|
|
def test_success_code_0(self):
|
2026-05-12 00:56:47 +08:00
|
|
|
errcode, detail = parse_wecom_error({"errcode": 0, "errmsg": "ok"})
|
|
|
|
|
assert errcode == 0
|
2026-05-13 16:43:01 +08:00
|
|
|
assert detail == "请求成功"
|
2026-05-12 00:56:47 +08:00
|
|
|
|
2026-05-13 16:43:01 +08:00
|
|
|
def test_system_busy(self):
|
|
|
|
|
errcode, detail = parse_wecom_error({"errcode": -1, "errmsg": "system busy"})
|
|
|
|
|
assert errcode == -1
|
|
|
|
|
assert detail == "系统繁忙,请稍后重试"
|
2026-05-12 00:56:47 +08:00
|
|
|
|
2026-05-13 16:43:01 +08:00
|
|
|
def test_invalid_secret(self):
|
|
|
|
|
errcode, detail = parse_wecom_error({"errcode": 40001, "errmsg": "invalid secret"})
|
|
|
|
|
assert errcode == 40001
|
|
|
|
|
assert detail == "不合法的secret参数"
|
2026-05-12 00:56:47 +08:00
|
|
|
|
2026-05-13 16:43:01 +08:00
|
|
|
def test_unknown_errcode_falls_back_to_errmsg(self):
|
2026-05-12 00:56:47 +08:00
|
|
|
errcode, detail = parse_wecom_error({"errcode": 99999, "errmsg": "custom error"})
|
|
|
|
|
assert errcode == 99999
|
2026-05-13 16:43:01 +08:00
|
|
|
assert detail == "custom error"
|
2026-05-12 00:56:47 +08:00
|
|
|
|
2026-05-13 16:43:01 +08:00
|
|
|
def test_missing_errcode_with_errmsg(self):
|
|
|
|
|
errcode, detail = parse_wecom_error({"errmsg": "some error"})
|
|
|
|
|
assert errcode == -1
|
|
|
|
|
assert detail == "some error"
|
2026-05-12 00:56:47 +08:00
|
|
|
|
2026-05-13 16:43:01 +08:00
|
|
|
def test_missing_errcode_no_errmsg(self):
|
2026-05-12 00:56:47 +08:00
|
|
|
errcode, detail = parse_wecom_error({})
|
|
|
|
|
assert errcode == -1
|
|
|
|
|
assert "未知错误" in detail
|
|
|
|
|
|
2026-05-13 16:43:01 +08:00
|
|
|
def test_errcode_not_in_data(self):
|
|
|
|
|
errcode, detail = parse_wecom_error({"other": "value"})
|
|
|
|
|
assert errcode == -1
|
|
|
|
|
assert detail == "未知错误(err_code 缺失)"
|
|
|
|
|
|
|
|
|
|
def test_rate_limit_error(self):
|
|
|
|
|
errcode, detail = parse_wecom_error({"errcode": 45009, "errmsg": "api freq limit"})
|
|
|
|
|
assert errcode == 45009
|
|
|
|
|
assert detail == "接口调用超过限制"
|
|
|
|
|
|
|
|
|
|
def test_api_too_frequent(self):
|
|
|
|
|
errcode, detail = parse_wecom_error({"errcode": 45011, "errmsg": "too frequent"})
|
|
|
|
|
assert errcode == 45011
|
|
|
|
|
assert detail == "API调用过于频繁"
|
2026-05-12 00:56:47 +08:00
|
|
|
|
2026-05-13 16:43:01 +08:00
|
|
|
|
|
|
|
|
class TestParseMpError:
|
|
|
|
|
def test_success_code_0(self):
|
2026-05-12 00:56:47 +08:00
|
|
|
errcode, detail = parse_mp_error({"errcode": 0, "errmsg": "ok"})
|
|
|
|
|
assert errcode == 0
|
2026-05-13 16:43:01 +08:00
|
|
|
assert detail == "请求成功"
|
2026-05-12 00:56:47 +08:00
|
|
|
|
2026-05-13 16:43:01 +08:00
|
|
|
def test_system_busy(self):
|
|
|
|
|
errcode, detail = parse_mp_error({"errcode": -1, "errmsg": "system busy"})
|
|
|
|
|
assert errcode == -1
|
|
|
|
|
assert detail == "系统繁忙,请稍后重试"
|
2026-05-12 00:56:47 +08:00
|
|
|
|
2026-05-13 16:43:01 +08:00
|
|
|
def test_invalid_appid(self):
|
|
|
|
|
errcode, detail = parse_mp_error({"errcode": 40013, "errmsg": "invalid appid"})
|
|
|
|
|
assert errcode == 40013
|
|
|
|
|
assert detail == "不合法的AppID"
|
|
|
|
|
|
|
|
|
|
def test_unknown_errcode_falls_back_to_errmsg(self):
|
|
|
|
|
errcode, detail = parse_mp_error({"errcode": 88888, "errmsg": "mp custom error"})
|
|
|
|
|
assert errcode == 88888
|
|
|
|
|
assert detail == "mp custom error"
|
|
|
|
|
|
|
|
|
|
def test_missing_errcode(self):
|
|
|
|
|
errcode, detail = parse_mp_error({})
|
|
|
|
|
assert errcode == -1
|
|
|
|
|
assert "未知错误" in detail
|
|
|
|
|
|
|
|
|
|
def test_reply_timeout(self):
|
|
|
|
|
errcode, detail = parse_mp_error({"errcode": 45015, "errmsg": "reply timeout"})
|
|
|
|
|
assert errcode == 45015
|
|
|
|
|
assert detail == "回复时间超过限制"
|
|
|
|
|
|
|
|
|
|
def test_need_recipient_follow(self):
|
|
|
|
|
errcode, detail = parse_mp_error({"errcode": 43004, "errmsg": "need follow"})
|
2026-05-12 00:56:47 +08:00
|
|
|
assert errcode == 43004
|
2026-05-13 16:43:01 +08:00
|
|
|
assert detail == "需要接收者关注"
|
2026-05-12 00:56:47 +08:00
|
|
|
|
2026-05-13 16:43:01 +08:00
|
|
|
def test_token_timeout_mp(self):
|
|
|
|
|
errcode, detail = parse_mp_error({"errcode": 42001, "errmsg": "token timeout"})
|
|
|
|
|
assert errcode == 42001
|
|
|
|
|
assert detail == "access_token超时"
|
2026-05-12 00:56:47 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
class TestIsTokenExpired:
|
2026-05-13 16:43:01 +08:00
|
|
|
def test_errcode_40014_is_expired(self):
|
2026-05-12 00:56:47 +08:00
|
|
|
assert is_token_expired(40014) is True
|
|
|
|
|
|
2026-05-13 16:43:01 +08:00
|
|
|
def test_errcode_42001_is_expired(self):
|
2026-05-12 00:56:47 +08:00
|
|
|
assert is_token_expired(42001) is True
|
|
|
|
|
|
2026-05-13 16:43:01 +08:00
|
|
|
def test_success_code_not_expired(self):
|
2026-05-12 00:56:47 +08:00
|
|
|
assert is_token_expired(0) is False
|
|
|
|
|
|
2026-05-13 16:43:01 +08:00
|
|
|
def test_system_busy_not_expired(self):
|
|
|
|
|
assert is_token_expired(-1) is False
|
2026-05-12 00:56:47 +08:00
|
|
|
|
2026-05-13 16:43:01 +08:00
|
|
|
def test_unknown_code_not_expired(self):
|
|
|
|
|
assert is_token_expired(99999) is False
|
2026-05-12 00:56:47 +08:00
|
|
|
|
2026-05-13 16:43:01 +08:00
|
|
|
def test_none_expired_code(self):
|
|
|
|
|
assert is_token_expired(40001) is False
|