quick update
Some checks failed
CI/CD Pipeline / Code Quality Checks (push) Failing after 4m49s
CI/CD Pipeline / Security Scanning (push) Successful in 15s
CI/CD Pipeline / Tests (3.11) (push) Failing after 4m58s
CI/CD Pipeline / Tests (3.12) (push) Failing after 5m0s
CI/CD Pipeline / Build Docker Image (push) Has been skipped
Some checks failed
CI/CD Pipeline / Code Quality Checks (push) Failing after 4m49s
CI/CD Pipeline / Security Scanning (push) Successful in 15s
CI/CD Pipeline / Tests (3.11) (push) Failing after 4m58s
CI/CD Pipeline / Tests (3.12) (push) Failing after 5m0s
CI/CD Pipeline / Build Docker Image (push) Has been skipped
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
import pytest
|
||||
from pydantic import ValidationError
|
||||
|
||||
from guardden.config import Settings, _parse_id_list, _validate_discord_id
|
||||
from guardden.config import GuildDefaults, Settings, _parse_id_list, _validate_discord_id
|
||||
from guardden.services.automod import normalize_domain
|
||||
|
||||
|
||||
@@ -244,3 +244,143 @@ class TestSecurityImprovements:
|
||||
os.environ["GUARDDEN_OWNER_IDS"] = original_owners
|
||||
else:
|
||||
os.environ.pop("GUARDDEN_OWNER_IDS", None)
|
||||
|
||||
|
||||
class TestGuildDefaultsValidation:
|
||||
"""Test GuildDefaults model validation."""
|
||||
|
||||
def test_default_values(self):
|
||||
"""Test default factory creates valid GuildDefaults."""
|
||||
defaults = GuildDefaults()
|
||||
assert defaults.prefix == "!"
|
||||
assert defaults.locale == "en"
|
||||
assert defaults.automod_enabled is True
|
||||
assert defaults.ai_sensitivity == 80
|
||||
assert defaults.ai_confidence_threshold == 0.7
|
||||
assert defaults.verification_type == "button"
|
||||
|
||||
def test_ai_sensitivity_valid_range(self):
|
||||
"""Test ai_sensitivity accepts values 0-100."""
|
||||
assert GuildDefaults(ai_sensitivity=0).ai_sensitivity == 0
|
||||
assert GuildDefaults(ai_sensitivity=50).ai_sensitivity == 50
|
||||
assert GuildDefaults(ai_sensitivity=100).ai_sensitivity == 100
|
||||
|
||||
def test_ai_sensitivity_invalid_range(self):
|
||||
"""Test ai_sensitivity rejects values outside 0-100."""
|
||||
with pytest.raises(ValidationError):
|
||||
GuildDefaults(ai_sensitivity=-1)
|
||||
with pytest.raises(ValidationError):
|
||||
GuildDefaults(ai_sensitivity=101)
|
||||
|
||||
def test_ai_confidence_threshold_valid_range(self):
|
||||
"""Test ai_confidence_threshold accepts values 0.0-1.0."""
|
||||
assert GuildDefaults(ai_confidence_threshold=0.0).ai_confidence_threshold == 0.0
|
||||
assert GuildDefaults(ai_confidence_threshold=0.5).ai_confidence_threshold == 0.5
|
||||
assert GuildDefaults(ai_confidence_threshold=1.0).ai_confidence_threshold == 1.0
|
||||
|
||||
def test_ai_confidence_threshold_invalid_range(self):
|
||||
"""Test ai_confidence_threshold rejects values outside 0.0-1.0."""
|
||||
with pytest.raises(ValidationError):
|
||||
GuildDefaults(ai_confidence_threshold=-0.1)
|
||||
with pytest.raises(ValidationError):
|
||||
GuildDefaults(ai_confidence_threshold=1.1)
|
||||
|
||||
def test_verification_type_valid_values(self):
|
||||
"""Test verification_type only accepts valid types."""
|
||||
valid_types = ["button", "captcha", "math", "emoji"]
|
||||
for vtype in valid_types:
|
||||
assert GuildDefaults(verification_type=vtype).verification_type == vtype
|
||||
|
||||
def test_verification_type_invalid_values(self):
|
||||
"""Test verification_type rejects invalid types."""
|
||||
with pytest.raises(ValidationError):
|
||||
GuildDefaults(verification_type="invalid")
|
||||
with pytest.raises(ValidationError):
|
||||
GuildDefaults(verification_type="")
|
||||
|
||||
def test_positive_rate_limits(self):
|
||||
"""Test rate limit fields must be positive."""
|
||||
# Valid positive values
|
||||
defaults = GuildDefaults(
|
||||
message_rate_limit=1,
|
||||
message_rate_window=1,
|
||||
duplicate_threshold=1,
|
||||
mention_limit=1,
|
||||
mention_rate_limit=1,
|
||||
mention_rate_window=1,
|
||||
)
|
||||
assert defaults.message_rate_limit == 1
|
||||
|
||||
# Invalid zero or negative values
|
||||
with pytest.raises(ValidationError):
|
||||
GuildDefaults(message_rate_limit=0)
|
||||
with pytest.raises(ValidationError):
|
||||
GuildDefaults(message_rate_window=-1)
|
||||
|
||||
def test_prefix_length_constraints(self):
|
||||
"""Test prefix has length constraints."""
|
||||
# Valid prefixes
|
||||
assert GuildDefaults(prefix="!").prefix == "!"
|
||||
assert GuildDefaults(prefix="??").prefix == "??"
|
||||
assert GuildDefaults(prefix="!" * 10).prefix == "!" * 10
|
||||
|
||||
# Invalid: empty prefix
|
||||
with pytest.raises(ValidationError):
|
||||
GuildDefaults(prefix="")
|
||||
|
||||
# Invalid: too long
|
||||
with pytest.raises(ValidationError):
|
||||
GuildDefaults(prefix="!" * 11)
|
||||
|
||||
|
||||
class TestSettingsGuildDefaults:
|
||||
"""Test Settings.guild_default field."""
|
||||
|
||||
def test_guild_default_factory(self):
|
||||
"""Test guild_default uses factory default."""
|
||||
settings = Settings(discord_token="a" * 60)
|
||||
assert settings.guild_default is not None
|
||||
assert isinstance(settings.guild_default, GuildDefaults)
|
||||
assert settings.guild_default.prefix == "!"
|
||||
|
||||
def test_guild_default_custom_values(self):
|
||||
"""Test guild_default can be set with custom values."""
|
||||
custom_defaults = GuildDefaults(
|
||||
prefix="?",
|
||||
ai_sensitivity=50,
|
||||
verification_enabled=True,
|
||||
)
|
||||
settings = Settings(discord_token="a" * 60, guild_default=custom_defaults)
|
||||
assert settings.guild_default.prefix == "?"
|
||||
assert settings.guild_default.ai_sensitivity == 50
|
||||
assert settings.guild_default.verification_enabled is True
|
||||
|
||||
def test_strike_actions_default(self):
|
||||
"""Test strike_actions has correct default structure."""
|
||||
defaults = GuildDefaults()
|
||||
assert defaults.strike_actions == {
|
||||
"1": {"action": "warn"},
|
||||
"3": {"action": "timeout", "duration": 3600},
|
||||
"5": {"action": "kick"},
|
||||
"7": {"action": "ban"},
|
||||
}
|
||||
|
||||
def test_strike_actions_custom(self):
|
||||
"""Test strike_actions can be customized."""
|
||||
custom_actions = {
|
||||
"1": {"action": "warn"},
|
||||
"5": {"action": "ban"},
|
||||
}
|
||||
defaults = GuildDefaults(strike_actions=custom_actions)
|
||||
assert defaults.strike_actions == custom_actions
|
||||
|
||||
def test_scam_allowlist_default(self):
|
||||
"""Test scam_allowlist defaults to empty list."""
|
||||
defaults = GuildDefaults()
|
||||
assert defaults.scam_allowlist == []
|
||||
|
||||
def test_scam_allowlist_custom(self):
|
||||
"""Test scam_allowlist can be customized."""
|
||||
custom_list = ["discord.com", "github.com"]
|
||||
defaults = GuildDefaults(scam_allowlist=custom_list)
|
||||
assert defaults.scam_allowlist == custom_list
|
||||
|
||||
Reference in New Issue
Block a user