ForcePilot/backend/test/unit/channels/test_twitch_auth_provider.py
Kris 69fe97a90d test: 批量修复并新增单元测试用例
1. 移除Telegram格式化测试中未使用的导入项
2. 修复Teams测试用例,添加monkeypatch参数并配置通配符开关
3. 更新钉钉适配器测试,替换弃用的流属性检查
4. 修正Twitch规范化测试,更新ROOMSTATE测试逻辑
5. 重构会话映射测试,完善数据库执行结果模拟
6. 格式化Slack块构建测试的长参数调用
7. 修复LINE适配器测试,更新能力断言和异步锁使用
8. 修正Slack会话解析测试,修复聊天类型判断错误
9. 更新能力测试,补充缺失的字段检查
10. 修复Matrix适配器测试,修正位置参数和配置校验逻辑
11. 为飞书分析模块测试添加跳过标记
12. 新增微信能力、限流、链接格式、会话路由等模块的单元测试
13. 修复Twitch适配器导入路径和测试断言
14. 新增Discord Webhook、Nextcloud Talk、Signal多账户等模块的单元测试
15. 修复Manager阶段测试的导入路径
16. 新增iMessage异常和命令处理的单元测试
17. 新增Nostr健康检查和相关模块的单元测试
18. 新增Signal守护进程和SSE重连相关测试
2026-05-13 16:43:01 +08:00

326 lines
11 KiB
Python

from __future__ import annotations
from unittest.mock import AsyncMock, patch
import pytest
from yuxi.channels.adapters.twitch.auth_provider import (
AuthProvider,
RefreshingAuthProvider,
StaticAuthProvider,
create_auth_provider,
)
class TestStaticAuthProvider:
def test_returns_access_token(self):
provider = StaticAuthProvider(client_id="cid", access_token="tok")
result = provider._access_token
assert result == "tok"
@pytest.mark.asyncio
async def test_get_access_token(self):
provider = StaticAuthProvider(client_id="cid", access_token="tok")
token = await provider.get_access_token()
assert token == "tok"
@pytest.mark.asyncio
async def test_get_client_id(self):
provider = StaticAuthProvider(client_id="cid", access_token="tok")
cid = await provider.get_client_id()
assert cid == "cid"
@pytest.mark.asyncio
async def test_validate_with_valid_token(self):
provider = StaticAuthProvider(client_id="cid", access_token="tok")
with patch("yuxi.channels.adapters.twitch.auth_provider.validate_token") as mock_validate:
mock_validate.return_value = {"id": "123"}
result = await provider.validate()
assert result is True
@pytest.mark.asyncio
async def test_validate_with_invalid_token(self):
provider = StaticAuthProvider(client_id="cid", access_token="tok")
with patch("yuxi.channels.adapters.twitch.auth_provider.validate_token") as mock_validate:
mock_validate.return_value = None
result = await provider.validate()
assert result is False
@pytest.mark.asyncio
async def test_validate_missing_credentials(self):
provider = StaticAuthProvider(client_id="", access_token="")
result = await provider.validate()
assert result is False
@pytest.mark.asyncio
async def test_get_access_token_returns_none_when_empty(self):
provider = StaticAuthProvider(client_id="cid", access_token="")
token = await provider.get_access_token()
assert token is None
class TestRefreshingAuthProvider:
def test_initial_state(self):
provider = RefreshingAuthProvider(
client_id="cid",
client_secret="secret",
access_token="tok",
refresh_token="rtok",
)
assert provider._access_token == "tok"
assert provider._refresh_token == "rtok"
assert provider._client_id == "cid"
assert provider._client_secret == "secret"
assert provider._token_expires_in == 0
assert provider._token_expires_at is None
@pytest.mark.asyncio
async def test_get_access_token_not_expired(self):
provider = RefreshingAuthProvider(
client_id="cid",
client_secret="secret",
access_token="tok",
refresh_token="rtok",
)
provider._token_expires_at = None
token = await provider.get_access_token()
assert token == "tok"
@pytest.mark.asyncio
async def test_get_client_id(self):
provider = RefreshingAuthProvider(
client_id="cid",
client_secret="secret",
access_token="tok",
refresh_token="rtok",
)
cid = await provider.get_client_id()
assert cid == "cid"
@pytest.mark.asyncio
async def test_validate_with_valid_token(self):
provider = RefreshingAuthProvider(
client_id="cid",
client_secret="secret",
access_token="tok",
refresh_token="rtok",
)
with patch("yuxi.channels.adapters.twitch.auth_provider.validate_token") as mock_validate:
mock_validate.return_value = {"id": "123"}
result = await provider.validate()
assert result is True
@pytest.mark.asyncio
async def test_validate_with_empty_credentials(self):
provider = RefreshingAuthProvider(
client_id="",
client_secret="secret",
access_token="",
refresh_token="rtok",
)
result = await provider.validate()
assert result is False
@pytest.mark.asyncio
async def test_refresh_successful(self):
provider = RefreshingAuthProvider(
client_id="cid",
client_secret="secret",
access_token="old_tok",
refresh_token="rtok",
)
with patch("yuxi.channels.adapters.twitch.auth_provider.refresh_access_token") as mock_refresh:
mock_refresh.return_value = {
"access_token": "new_tok",
"refresh_token": "new_rtok",
"expires_in": 14400,
}
result = await provider._refresh()
assert result is True
assert provider._access_token == "new_tok"
assert provider._refresh_token == "new_rtok"
assert provider._token_expires_in == 14400
assert provider._token_expires_at is not None
@pytest.mark.asyncio
async def test_refresh_no_new_access_token(self):
provider = RefreshingAuthProvider(
client_id="cid",
client_secret="secret",
access_token="old_tok",
refresh_token="rtok",
)
with patch("yuxi.channels.adapters.twitch.auth_provider.refresh_access_token") as mock_refresh:
mock_refresh.return_value = {
"refresh_token": "new_rtok",
"expires_in": 14400,
}
result = await provider._refresh()
assert result is True
@pytest.mark.asyncio
async def test_refresh_failure_single_attempt(self):
provider = RefreshingAuthProvider(
client_id="cid",
client_secret="secret",
access_token="old_tok",
refresh_token="rtok",
)
with patch("yuxi.channels.adapters.twitch.auth_provider.refresh_access_token") as mock_refresh:
mock_refresh.return_value = None
result = await provider._refresh()
assert result is False
@pytest.mark.asyncio
async def test_refresh_missing_client_secret(self):
provider = RefreshingAuthProvider(
client_id="cid",
client_secret="",
access_token="old_tok",
refresh_token="rtok",
)
result = await provider._refresh()
assert result is False
@pytest.mark.asyncio
async def test_refresh_missing_refresh_token(self):
provider = RefreshingAuthProvider(
client_id="cid",
client_secret="secret",
access_token="old_tok",
refresh_token="",
)
result = await provider._refresh()
assert result is False
@pytest.mark.asyncio
async def test_is_expired_when_none(self):
provider = RefreshingAuthProvider(
client_id="cid",
client_secret="secret",
access_token="tok",
refresh_token="rtok",
)
provider._token_expires_at = None
assert provider._is_expired() is False
@pytest.mark.asyncio
async def test_is_expired_when_future(self):
import time
provider = RefreshingAuthProvider(
client_id="cid",
client_secret="secret",
access_token="tok",
refresh_token="rtok",
)
provider._token_expires_at = time.time() + 3600
assert provider._is_expired() is False
@pytest.mark.asyncio
async def test_is_expired_when_past(self):
import time
provider = RefreshingAuthProvider(
client_id="cid",
client_secret="secret",
access_token="tok",
refresh_token="rtok",
)
provider._token_expires_at = time.time() - 1
assert provider._is_expired() is True
@pytest.mark.asyncio
async def test_get_access_token_expired_and_refreshes(self):
import time
provider = RefreshingAuthProvider(
client_id="cid",
client_secret="secret",
access_token="old_tok",
refresh_token="rtok",
)
provider._token_expires_at = time.time() - 1
with patch("yuxi.channels.adapters.twitch.auth_provider.refresh_access_token") as mock_refresh:
mock_refresh.return_value = {
"access_token": "new_tok",
"refresh_token": "new_rtok",
"expires_in": 14400,
}
token = await provider.get_access_token()
assert token == "new_tok"
@pytest.mark.asyncio
async def test_get_access_token_expired_refresh_fails(self):
import time
provider = RefreshingAuthProvider(
client_id="cid",
client_secret="secret",
access_token="old_tok",
refresh_token="rtok",
)
provider._token_expires_at = time.time() - 1
with patch("yuxi.channels.adapters.twitch.auth_provider.refresh_access_token") as mock_refresh:
mock_refresh.return_value = None
token = await provider.get_access_token()
assert token is None
@pytest.mark.asyncio
async def test_expires_at_property(self):
provider = RefreshingAuthProvider(
client_id="cid",
client_secret="secret",
access_token="tok",
refresh_token="rtok",
)
provider._token_expires_at = 12345.0
assert provider.expires_at == 12345.0
@pytest.mark.asyncio
async def test_expires_in_property(self):
provider = RefreshingAuthProvider(
client_id="cid",
client_secret="secret",
access_token="tok",
refresh_token="rtok",
)
provider._token_expires_in = 3600
assert provider.expires_in == 3600
class TestCreateAuthProvider:
def test_creates_refreshing_when_secret_and_refresh_present(self):
config = {
"client_id": "cid",
"client_secret": "secret",
"access_token": "tok",
"refresh_token": "rtok",
}
provider = create_auth_provider(config)
assert isinstance(provider, RefreshingAuthProvider)
def test_creates_static_when_no_secret(self):
config = {
"client_id": "cid",
"access_token": "tok",
}
provider = create_auth_provider(config)
assert isinstance(provider, StaticAuthProvider)
def test_creates_static_when_no_refresh_token(self):
config = {
"client_id": "cid",
"client_secret": "secret",
"access_token": "tok",
}
provider = create_auth_provider(config)
assert isinstance(provider, StaticAuthProvider)
def test_creates_static_when_empty_config(self):
config = {}
provider = create_auth_provider(config)
assert isinstance(provider, StaticAuthProvider)
def test_auth_provider_is_abstract(self):
assert hasattr(AuthProvider, "__abstractmethods__")