Files
chisup/tests/test_chis_auth.py
T
2026-07-05 11:13:34 +08:00

201 lines
6.3 KiB
Python

import pytest
from app.chis.auth import ChisLoginClient, ChisLoginError
class FakeTransport:
def __init__(self, responses):
self.responses = list(responses)
self.calls = []
def post(self, url, headers, payload):
self.calls.append({"url": url, "headers": headers, "payload": payload})
return self.responses.pop(0)
def fake_encrypt(public_key, raw_text):
if raw_text == "secret":
return "encrypted-password"
if raw_text == "1234567890":
return "encrypted-time"
return "encrypted-value"
def test_login_gets_role_apps_and_cookie_without_leaking_password():
transport = FakeTransport(
[
(
{
"code": 200,
"body": {
"tokens": [
{"roleName": "其他角色", "id": "1", "userName": "ignored"},
{"roleName": "责任医生", "id": "role-2", "userName": "doctor"},
]
},
},
{"Set-Cookie": "JSESSIONID=abc123; Path=/chis; HttpOnly"},
),
({"code": 200, "body": {"apps": []}}, {}),
]
)
client = ChisLoginClient(
base_url="http://chis.example.test/chis",
public_key="public-key",
transport=transport,
encrypt=fake_encrypt,
now_millis=lambda: 1234567890,
)
session = client.login(username="u001", password="secret")
assert session.cookie == "JSESSIONID=abc123; sessionId1=abc123; u001=%E8%B4%A3%E4%BB%BB%E5%8C%BB%E7%94%9F@photo/default.jpg"
assert session.role_id == "role-2"
assert session.role_name == "责任医生"
assert session.user_name == "doctor"
assert transport.calls[0]["url"] == "http://chis.example.test/chis/logon/myRoles"
assert transport.calls[0]["payload"] == {
"url": "logon/myRoles",
"uid": "u001",
"pwd": "encrypted-password",
"d": "encrypted-time",
}
assert "secret" not in str(transport.calls)
assert transport.calls[1]["url"].startswith("http://chis.example.test/chis/logon/myApps?")
assert transport.calls[1]["headers"]["Cookie"] == "JSESSIONID=abc123"
assert "urt=role-2" in transport.calls[1]["url"]
def test_login_raises_clear_error_when_roles_fail():
transport = FakeTransport([({"code": 501, "msg": "PasswordNotRight"}, {})])
client = ChisLoginClient(
base_url="http://chis.example.test/chis",
public_key="public-key",
transport=transport,
encrypt=fake_encrypt,
)
with pytest.raises(ChisLoginError) as exc_info:
client.login(username="u001", password="secret")
assert exc_info.value.code == "chis_login_failed"
assert "PasswordNotRight" in str(exc_info.value)
assert "secret" not in str(exc_info.value)
def test_login_raises_clear_error_when_required_role_missing():
transport = FakeTransport(
[
(
{
"code": 200,
"body": {
"tokens": [
{"roleName": "其他角色", "id": "1", "userName": "ignored"},
]
},
},
{"Set-Cookie": "JSESSIONID=abc123; Path=/chis"},
),
]
)
client = ChisLoginClient(
base_url="http://chis.example.test/chis",
public_key="public-key",
transport=transport,
encrypt=fake_encrypt,
)
with pytest.raises(ChisLoginError) as exc_info:
client.login(username="u001", password="secret")
assert exc_info.value.code == "chis_role_not_allowed"
assert "责任医生助理" in str(exc_info.value)
assert "责任医生" in str(exc_info.value)
def test_requests_transport_uses_proxy_when_configured():
client = ChisLoginClient.from_config(
{
"CHIS_BASE_URL": "http://chis.example.test/chis",
"CHIS_PUBLIC_KEY": "public-key",
"CHIS_PROXY": "socks5h://127.0.0.1:1080",
}
)
assert client.transport.session.proxies["http"] == "socks5h://127.0.0.1:1080"
assert client.transport.session.proxies["https"] == "socks5h://127.0.0.1:1080"
def test_requests_transport_direct_when_proxy_empty():
client = ChisLoginClient.from_config(
{
"CHIS_BASE_URL": "http://chis.example.test/chis",
"CHIS_PUBLIC_KEY": "public-key",
"CHIS_PROXY": "",
}
)
assert client.transport.session.proxies == {}
def test_login_client_accepts_plain_host_config():
client = ChisLoginClient(
base_url="chis.example.test:9002",
public_key="public-key",
transport=FakeTransport([]),
encrypt=fake_encrypt,
)
assert client.base_url == "http://chis.example.test:9002/chis"
assert client.host == "chis.example.test:9002"
def test_get_lander_info_uses_existing_cookie_to_query_account_info():
transport = FakeTransport(
[
(
{
"code": 200,
"body": {"userId": "u001", "userName": "doctor"},
"msg": "success",
},
{},
),
]
)
client = ChisLoginClient(
base_url="http://chis.example.test/chis",
public_key="public-key",
transport=transport,
encrypt=fake_encrypt,
)
result = client.get_lander_info("JSESSIONID=abc123; sessionId1=abc123")
assert result["body"]["userId"] == "u001"
assert transport.calls[0]["url"] == "http://chis.example.test/chis/*.jsonRequest?"
assert transport.calls[0]["headers"]["Cookie"] == "JSESSIONID=abc123; sessionId1=abc123"
assert transport.calls[0]["payload"] == {
"serviceId": "chis.myPageService",
"serviceAction": "getLanderInfo",
"method": "execute",
}
def test_get_lander_info_raises_session_invalid_when_chis_rejects_cookie():
transport = FakeTransport([({"code": 403, "msg": "not login"}, {})])
client = ChisLoginClient(
base_url="http://chis.example.test/chis",
public_key="public-key",
transport=transport,
encrypt=fake_encrypt,
)
with pytest.raises(ChisLoginError) as exc_info:
client.get_lander_info("JSESSIONID=expired")
assert exc_info.value.code == "chis_session_invalid"
assert "not login" in str(exc_info.value)