ForcePilot/backend/test/unit/channel/adapters/test_adapters.py
Kris bab30f2715
Some checks failed
Deploy VitePress site to Pages / build (push) Has been cancelled
Ruff Format Check / Ruff Format & Lint (push) Has been cancelled
Deploy VitePress site to Pages / Deploy (push) Has been cancelled
feat:0715
2026-07-15 12:30:58 +08:00

106 lines
3.6 KiB
Python

from __future__ import annotations
import pytest
from yuxi.channel.adapters import (
HttpErrorClassifier,
MediaUploadAdapter,
TokenAuthAdapter,
TypingIndicatorAdapter,
WebhookSignatureAdapter,
)
from yuxi.channel.exceptions import ChannelErrorClassification
class TestHttpErrorClassifier:
@pytest.fixture
def classifier(self):
return HttpErrorClassifier()
def test_429_returns_rate_limited(self, classifier):
assert classifier.classify(429) == ChannelErrorClassification.RATE_LIMITED
def test_400_returns_permanent(self, classifier):
assert classifier.classify(400) == ChannelErrorClassification.PERMANENT
def test_404_returns_permanent(self, classifier):
assert classifier.classify(404) == ChannelErrorClassification.PERMANENT
def test_500_returns_retryable(self, classifier):
assert classifier.classify(500) == ChannelErrorClassification.RETRYABLE
def test_503_returns_retryable(self, classifier):
assert classifier.classify(503) == ChannelErrorClassification.RETRYABLE
def test_none_status_returns_retryable(self, classifier):
assert classifier.classify(None) == ChannelErrorClassification.RETRYABLE
class TestMediaUploadAdapter:
@pytest.fixture
def adapter(self):
return MediaUploadAdapter(base_url="https://example.com")
async def test_upload_returns_none(self, adapter):
assert await adapter.upload({"url": "a.jpg"}) is None
async def test_download_returns_none(self, adapter):
assert await adapter.download("https://example.com/a.jpg") is None
def test_base_url_stored(self):
adapter = MediaUploadAdapter(base_url="https://cdn.example.com")
assert adapter.base_url == "https://cdn.example.com"
class TestTokenAuthAdapter:
@pytest.fixture
def adapter(self):
return TokenAuthAdapter(app_id="app", app_secret="secret", token_url="https://example.com/token")
async def test_get_token_returns_none(self, adapter):
assert await adapter.get_token() is None
async def test_refresh_token_returns_none(self, adapter):
assert await adapter.refresh_token() is None
def test_credentials_stored(self):
adapter = TokenAuthAdapter(app_id="a", app_secret="s", token_url="https://t")
assert adapter.app_id == "a"
assert adapter.app_secret == "s"
assert adapter.token_url == "https://t"
class TestTypingIndicatorAdapter:
@pytest.fixture
def adapter(self):
return TypingIndicatorAdapter(interval_seconds=3.0)
async def test_start_returns_none(self, adapter):
assert await adapter.start("session-1") is None
async def test_stop_returns_none(self, adapter):
assert await adapter.stop("session-1") is None
def test_interval_stored(self):
adapter = TypingIndicatorAdapter(interval_seconds=7.0)
assert adapter.interval_seconds == 7.0
class TestWebhookSignatureAdapter:
@pytest.fixture
def adapter(self):
return WebhookSignatureAdapter(secret="shhh", signature_header="X-Signature")
def test_compute_signature_returns_none(self, adapter):
assert adapter.compute_signature(b"body") is None
def test_validate_with_no_signature_returns_true(self, adapter):
assert adapter.validate(b"body", None) is True
def test_validate_with_signature_returns_false(self, adapter):
assert adapter.validate(b"body", "sig") is False
def test_config_stored(self):
adapter = WebhookSignatureAdapter(secret="secret", signature_header="X-Hub-Signature")
assert adapter.secret == "secret"
assert adapter.signature_header == "X-Hub-Signature"