from __future__ import annotations from yuxi.channel import constants class TestUserChannelType: def test_members(self): assert constants.UserChannelType.FEISHU == "feishu" assert constants.UserChannelType.DINGTALK == "dingtalk" assert constants.UserChannelType.WECOM == "wecom" assert constants.UserChannelType.SLACK == "slack" assert constants.UserChannelType.TELEGRAM == "telegram" assert constants.UserChannelType.OPEN_API == "open_api" assert constants.UserChannelType.MANUAL == "manual" assert constants.UserChannelType.SSO == "sso" class TestDeliveryStatus: def test_members(self): assert constants.DeliveryStatus.COMPLETE == "complete" assert constants.DeliveryStatus.PARTIAL_FAILED == "partial_failed" assert constants.DeliveryStatus.FAILED == "failed" assert constants.DeliveryStatus.DEAD_LETTER == "dead_letter" assert constants.DeliveryStatus.PENDING == "pending" class TestDispatchResult: def test_members(self): assert constants.DispatchResult.SUCCESS == "success" assert constants.DispatchResult.PERMANENT_FAILURE == "permanent_failure" assert constants.DispatchResult.RETRYABLE == "retryable" class TestInboundRejectionReason: def test_members(self): assert constants.InboundRejectionReason.DUPLICATE == "duplicate" assert constants.InboundRejectionReason.UNKNOWN_CHANNEL == "unknown_channel" assert constants.InboundRejectionReason.CONFIG_ERROR == "config_error" assert constants.InboundRejectionReason.SECURITY_REJECTED == "security_rejected" assert constants.InboundRejectionReason.DM_NOT_ALLOWED == "dm_not_allowed" assert constants.InboundRejectionReason.DM_PAIRING_REQUIRED == "dm_pairing_required" assert constants.InboundRejectionReason.GROUP_NOT_ALLOWED == "group_not_allowed" assert constants.InboundRejectionReason.BOT_LOOP_DETECTED == "bot_loop_detected" assert constants.InboundRejectionReason.RATE_LIMITED == "rate_limited" assert constants.InboundRejectionReason.INTERNAL_ERROR == "internal_error" class TestRedisKeys: def test_channel_stream_key(self): assert constants.CHANNEL_STREAM_KEY == "ch:messages" def test_channel_consumer_group(self): assert constants.CHANNEL_CONSUMER_GROUP == "ch:dispatchers" def test_channel_config_change_channel(self): assert constants.CHANNEL_CONFIG_CHANGE_CHANNEL == "ch:config:changed" def test_key_templates(self): assert constants.CHANNEL_PROCESSED_KEY_TEMPLATE == "ch:processed:{message_id}" assert constants.CHANNEL_DELIVERED_KEY_TEMPLATE == "ch:delivered:{message_id}" assert constants.CHANNEL_PROCESSING_KEY_TEMPLATE == "ch:processing:{message_id}" assert constants.CHANNEL_PUBLISHING_KEY_TEMPLATE == "ch:publishing:{message_id}" assert constants.CHANNEL_COMPENSATE_LOCK_KEY == "ch:compensate:lock" assert constants.CHANNEL_RATE_LIMIT_KEY_TEMPLATE == "ch:rate:{channel_type}:{account_id}:{actor_id}" class TestTtlConstants: def test_delivery_ttl(self): assert constants.CHANNEL_DELIVERED_TTL_SECONDS == 7 * 24 * 3600 def test_processing_lock_ttl(self): assert constants.CHANNEL_PROCESSING_LOCK_TTL_SECONDS == 300 def test_processing_lock_renew_interval(self): assert constants.CHANNEL_PROCESSING_LOCK_RENEW_INTERVAL_SECONDS == 60 def test_publishing_lock_ttl(self): assert constants.CHANNEL_PUBLISHING_LOCK_TTL_SECONDS == 300 def test_processed_ttl(self): assert constants.CHANNEL_PROCESSED_TTL_SECONDS == 300 def test_compensate_lock_ttl(self): assert constants.CHANNEL_COMPENSATE_LOCK_TTL_SECONDS == 300 class TestBackoffConstants: def test_max_delivery_attempts(self): assert constants.CHANNEL_MAX_DELIVERY_ATTEMPTS == 5 def test_max_compensate_attempts(self): assert constants.CHANNEL_MAX_COMPENSATE_ATTEMPTS == 5 def test_backoff_base(self): assert constants.CHANNEL_BACKOFF_BASE_SECONDS == 2 def test_backoff_max(self): assert constants.CHANNEL_BACKOFF_MAX_SECONDS == 3600 class TestKeyHelperFunctions: def test_channel_processed_key(self): assert constants.channel_processed_key("msg-1") == "ch:processed:msg-1" assert constants.channel_processed_key(None) == "ch:processed:unknown" def test_channel_delivered_key(self): assert constants.channel_delivered_key("msg-1") == "ch:delivered:msg-1" assert constants.channel_delivered_key(123) == "ch:delivered:123" def test_channel_processing_key(self): assert constants.channel_processing_key("msg-1") == "ch:processing:msg-1" def test_channel_publishing_key(self): assert constants.channel_publishing_key("msg-1") == "ch:publishing:msg-1" def test_channel_rate_limit_key(self): assert constants.channel_rate_limit_key("feishu", "acc-1", "user-1") == "ch:rate:feishu:acc-1:user-1" def test_pending_claim_min_idle_ms(self): expected = (constants.CHANNEL_PROCESSING_LOCK_TTL_SECONDS + 10) * 1000 assert constants.CHANNEL_PENDING_CLAIM_MIN_IDLE_MS == expected