All checks were successful
ci / ci (push) Successful in 1m3s
- tests/test_data.py: models serialization, enums, roundtrip - tests/test_storage.py: CRUD JSON, cache, persistence - tests/test_transcript.py: HTML generation, escaping, attachments - tests/test_ui.py: button callbacks with mocked interactions - Fixed: transcript.py attachments access (dataclass not dict)
244 lines
7.5 KiB
Python
244 lines
7.5 KiB
Python
from __future__ import annotations
|
|
|
|
from tickets.data import (
|
|
GuildTicketConfig,
|
|
TicketCategory,
|
|
TicketData,
|
|
TicketMessage,
|
|
TicketPriority,
|
|
TicketStatus,
|
|
)
|
|
|
|
|
|
class TestTicketStatus:
|
|
def test_open_value(self):
|
|
assert TicketStatus.OPEN.value == "open"
|
|
|
|
def test_closed_value(self):
|
|
assert TicketStatus.CLOSED.value == "closed"
|
|
|
|
def test_enum_inheritance(self):
|
|
assert issubclass(TicketStatus, str)
|
|
|
|
|
|
class TestTicketPriority:
|
|
def test_all_values(self):
|
|
assert TicketPriority.LOW.value == "low"
|
|
assert TicketPriority.NORMAL.value == "normal"
|
|
assert TicketPriority.HIGH.value == "high"
|
|
assert TicketPriority.URGENT.value == "urgent"
|
|
|
|
|
|
class TestTicketCategory:
|
|
def test_create_default(self):
|
|
cat = TicketCategory(id="test", name="Test")
|
|
assert cat.id == "test"
|
|
assert cat.name == "Test"
|
|
assert cat.emoji == ""
|
|
assert cat.description == ""
|
|
assert cat.staff_role_id is None
|
|
assert cat.discord_category_id is None
|
|
|
|
def test_to_dict(self):
|
|
cat = TicketCategory(
|
|
id="support",
|
|
name="Support",
|
|
emoji="🎫",
|
|
description="Aide",
|
|
staff_role_id=123,
|
|
discord_category_id=456,
|
|
)
|
|
d = cat.to_dict()
|
|
assert d["id"] == "support"
|
|
assert d["name"] == "Support"
|
|
assert d["emoji"] == "🎫"
|
|
assert d["description"] == "Aide"
|
|
assert d["staff_role_id"] == 123
|
|
assert d["discord_category_id"] == 456
|
|
|
|
def test_from_dict(self):
|
|
d = {
|
|
"id": "support",
|
|
"name": "Support",
|
|
"emoji": "🎫",
|
|
"description": "Aide",
|
|
"staff_role_id": 123,
|
|
"discord_category_id": 456,
|
|
}
|
|
cat = TicketCategory.from_dict(d)
|
|
assert cat.id == "support"
|
|
assert cat.name == "Support"
|
|
assert cat.staff_role_id == 123
|
|
|
|
def test_from_dict_ignores_extra_keys(self):
|
|
d = {"id": "x", "name": "X", "unknown_key": "should be ignored"}
|
|
cat = TicketCategory.from_dict(d)
|
|
assert cat.id == "x"
|
|
|
|
def test_roundtrip(self):
|
|
cat = TicketCategory(id="a", name="A", emoji="🔧", description="desc")
|
|
cat2 = TicketCategory.from_dict(cat.to_dict())
|
|
assert cat2 == cat
|
|
|
|
|
|
class TestTicketMessage:
|
|
def test_create_minimal(self):
|
|
msg = TicketMessage(author_id=1, author_name="user", content="hello", timestamp="2026-01-01")
|
|
assert msg.attachments == []
|
|
assert msg.is_staff is False
|
|
|
|
def test_create_full(self):
|
|
msg = TicketMessage(
|
|
author_id=1,
|
|
author_name="user",
|
|
content="hello",
|
|
timestamp="2026-01-01",
|
|
attachments=["a.png"],
|
|
is_staff=True,
|
|
)
|
|
assert msg.attachments == ["a.png"]
|
|
assert msg.is_staff is True
|
|
|
|
|
|
class TestTicketData:
|
|
def test_create_minimal(self):
|
|
t = TicketData(channel_id=1, guild_id=2, user_id=3, category_id="cat")
|
|
assert t.status == TicketStatus.OPEN
|
|
assert t.priority == TicketPriority.NORMAL
|
|
assert t.locked is False
|
|
assert t.claimed_by is None
|
|
assert t.messages == []
|
|
assert t.reason == ""
|
|
|
|
def test_to_dict(self):
|
|
t = TicketData(
|
|
channel_id=100,
|
|
guild_id=200,
|
|
user_id=300,
|
|
category_id="support",
|
|
status=TicketStatus.CLOSED,
|
|
priority=TicketPriority.HIGH,
|
|
claimed_by=999,
|
|
locked=True,
|
|
reason="test",
|
|
)
|
|
d = t.to_dict()
|
|
assert d["channel_id"] == 100
|
|
assert d["status"] == "closed"
|
|
assert d["priority"] == "high"
|
|
assert d["claimed_by"] == 999
|
|
assert d["locked"] is True
|
|
assert d["reason"] == "test"
|
|
|
|
def test_to_dict_with_messages(self):
|
|
t = TicketData(channel_id=1, guild_id=2, user_id=3, category_id="c")
|
|
t.messages.append(TicketMessage(author_id=1, author_name="a", content="hi", timestamp="t"))
|
|
d = t.to_dict()
|
|
assert len(d["messages"]) == 1
|
|
assert d["messages"][0]["content"] == "hi"
|
|
|
|
def test_from_dict(self):
|
|
d = {
|
|
"channel_id": 1,
|
|
"guild_id": 2,
|
|
"user_id": 3,
|
|
"category_id": "c",
|
|
"status": "closed",
|
|
"priority": "high",
|
|
"claimed_by": 99,
|
|
"locked": True,
|
|
"reason": "r",
|
|
"messages": [{"author_id": 1, "author_name": "a", "content": "hi", "timestamp": "t"}],
|
|
}
|
|
t = TicketData.from_dict(d)
|
|
assert t.status == TicketStatus.CLOSED
|
|
assert t.priority == TicketPriority.HIGH
|
|
assert t.claimed_by == 99
|
|
assert t.locked is True
|
|
assert len(t.messages) == 1
|
|
|
|
def test_from_dict_legacy_keys(self):
|
|
d = {
|
|
"channel_id": 1,
|
|
"guild_id": 2,
|
|
"user_id": 3,
|
|
"category_id": "c",
|
|
"transcript_path": "/old/path.html",
|
|
"rating": 5,
|
|
"feedback": "ok",
|
|
}
|
|
t = TicketData.from_dict(d)
|
|
assert not hasattr(t, "transcript_path")
|
|
assert not hasattr(t, "rating")
|
|
assert not hasattr(t, "feedback")
|
|
|
|
def test_roundtrip(self):
|
|
t = TicketData(
|
|
channel_id=10,
|
|
guild_id=20,
|
|
user_id=30,
|
|
category_id="cat",
|
|
status=TicketStatus.CLOSED,
|
|
priority=TicketPriority.URGENT,
|
|
claimed_by=50,
|
|
locked=True,
|
|
reason="test reason",
|
|
created_at="2026-01-01T00:00:00",
|
|
closed_at="2026-01-02T00:00:00",
|
|
)
|
|
t.messages.append(TicketMessage(author_id=1, author_name="u", content="m", timestamp="t"))
|
|
t2 = TicketData.from_dict(t.to_dict())
|
|
assert t2.channel_id == t.channel_id
|
|
assert t2.status == t.status
|
|
assert t2.priority == t.priority
|
|
assert t2.claimed_by == t.claimed_by
|
|
assert t2.locked == t.locked
|
|
assert len(t2.messages) == 1
|
|
|
|
|
|
class TestGuildTicketConfig:
|
|
def test_create_default(self):
|
|
c = GuildTicketConfig(guild_id=1)
|
|
assert c.enabled is False
|
|
assert c.categories == []
|
|
assert c.staff_role_id is None
|
|
assert c.log_channel_id is None
|
|
assert c.transcript_enabled is True
|
|
|
|
def test_to_dict(self):
|
|
c = GuildTicketConfig(
|
|
guild_id=1,
|
|
enabled=True,
|
|
staff_role_id=100,
|
|
log_channel_id=200,
|
|
panel_channel_id=300,
|
|
panel_message_id=400,
|
|
)
|
|
c.categories.append(TicketCategory(id="a", name="A"))
|
|
d = c.to_dict()
|
|
assert d["guild_id"] == 1
|
|
assert d["enabled"] is True
|
|
assert d["staff_role_id"] == 100
|
|
assert d["log_channel_id"] == 200
|
|
assert len(d["categories"]) == 1
|
|
|
|
def test_from_dict(self):
|
|
d = {
|
|
"guild_id": 1,
|
|
"enabled": True,
|
|
"staff_role_id": 100,
|
|
"log_channel_id": 200,
|
|
"categories": [{"id": "a", "name": "A"}],
|
|
}
|
|
c = GuildTicketConfig.from_dict(d)
|
|
assert c.enabled is True
|
|
assert len(c.categories) == 1
|
|
assert c.categories[0].id == "a"
|
|
|
|
def test_roundtrip(self):
|
|
c = GuildTicketConfig(guild_id=42, enabled=True)
|
|
c.categories.append(TicketCategory(id="x", name="X", emoji="🔧"))
|
|
c2 = GuildTicketConfig.from_dict(c.to_dict())
|
|
assert c2.guild_id == 42
|
|
assert c2.enabled is True
|
|
assert c2.categories[0].id == "x"
|