Files
BanGUI/backend/tests/test_mappers/test_ban_mappers.py
Lukas 3888c5eb3f Refactor ban management with domain models and mappers
- Add ban domain model for core business logic separation
- Implement mapper pattern for DTO/domain conversions
- Update ban service with new domain-driven approach
- Refactor router endpoints to use new architecture
- Add comprehensive mapper tests
- Update documentation with architecture changes

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-28 07:46:02 +02:00

221 lines
7.1 KiB
Python

"""Tests for ban response mappers."""
from app.mappers import (
map_domain_active_ban_list_to_response,
map_domain_active_ban_to_response,
map_domain_bans_by_country_to_response,
map_domain_bans_by_jail_to_response,
map_domain_ban_trend_to_response,
map_domain_dashboard_ban_item_to_response,
map_domain_dashboard_ban_list_to_response,
)
from app.models.ban_domain import (
DomainActiveBan,
DomainActiveBanList,
DomainBansByCountry,
DomainBansByJail,
DomainBanTrend,
DomainBanTrendBucket,
DomainDashboardBanItem,
DomainDashboardBanList,
DomainJailBanCount,
)
class TestActiveBanMapper:
"""Test mapping from DomainActiveBan to ActiveBan."""
def test_maps_all_fields(self) -> None:
"""All fields are correctly mapped."""
domain_ban = DomainActiveBan(
ip="192.168.1.1",
jail="sshd",
banned_at="2026-04-28T07:00:00+00:00",
expires_at="2026-04-28T08:00:00+00:00",
ban_count=3,
country="DE",
)
result = map_domain_active_ban_to_response(domain_ban)
assert result.ip == "192.168.1.1"
assert result.jail == "sshd"
assert result.banned_at == "2026-04-28T07:00:00+00:00"
assert result.expires_at == "2026-04-28T08:00:00+00:00"
assert result.ban_count == 3
assert result.country == "DE"
def test_handles_null_timestamps(self) -> None:
"""Null timestamps are preserved."""
domain_ban = DomainActiveBan(
ip="10.0.0.1",
jail="test",
banned_at=None,
expires_at=None,
)
result = map_domain_active_ban_to_response(domain_ban)
assert result.banned_at is None
assert result.expires_at is None
class TestActiveBanListMapper:
"""Test mapping from DomainActiveBanList to ActiveBanListResponse."""
def test_maps_list_and_total(self) -> None:
"""List and total are correctly mapped."""
domain_list = DomainActiveBanList(
bans=[
DomainActiveBan(ip="1.1.1.1", jail="sshd", ban_count=1),
DomainActiveBan(ip="2.2.2.2", jail="httpd", ban_count=2),
],
total=2,
)
result = map_domain_active_ban_list_to_response(domain_list)
assert result.total == 2
assert len(result.bans) == 2
assert result.bans[0].ip == "1.1.1.1"
assert result.bans[1].ip == "2.2.2.2"
def test_handles_empty_list(self) -> None:
"""Empty list is handled correctly."""
domain_list = DomainActiveBanList(bans=[], total=0)
result = map_domain_active_ban_list_to_response(domain_list)
assert result.total == 0
assert len(result.bans) == 0
class TestDashboardBanItemMapper:
"""Test mapping from DomainDashboardBanItem to DashboardBanItem."""
def test_maps_all_fields(self) -> None:
"""All fields are correctly mapped."""
domain_item = DomainDashboardBanItem(
ip="203.0.113.1",
jail="sshd",
banned_at="2026-04-28T07:00:00+00:00",
service="SSH login attempt",
country_code="US",
country_name="United States",
asn="AS15169",
org="Google LLC",
ban_count=5,
origin="selfblock",
)
result = map_domain_dashboard_ban_item_to_response(domain_item)
assert result.ip == "203.0.113.1"
assert result.jail == "sshd"
assert result.banned_at == "2026-04-28T07:00:00+00:00"
assert result.service == "SSH login attempt"
assert result.country_code == "US"
assert result.country_name == "United States"
assert result.asn == "AS15169"
assert result.org == "Google LLC"
assert result.ban_count == 5
assert result.origin == "selfblock"
class TestDashboardBanListMapper:
"""Test mapping from DomainDashboardBanList to DashboardBanListResponse."""
def test_maps_pagination_and_items(self) -> None:
"""Pagination metadata and items are correctly mapped."""
domain_list = DomainDashboardBanList(
items=[
DomainDashboardBanItem(
ip="1.1.1.1",
jail="sshd",
banned_at="2026-04-28T07:00:00+00:00",
ban_count=1,
),
],
total=100,
page=2,
page_size=50,
)
result = map_domain_dashboard_ban_list_to_response(domain_list)
assert result.total == 100
assert result.page == 2
assert result.page_size == 50
assert len(result.items) == 1
assert result.items[0].ip == "1.1.1.1"
class TestBansByCountryMapper:
"""Test mapping from DomainBansByCountry to BansByCountryResponse."""
def test_maps_aggregation_and_items(self) -> None:
"""Country aggregation and companion items are correctly mapped."""
domain_data = DomainBansByCountry(
countries={"US": 10, "DE": 5, "GB": 3},
country_names={"US": "United States", "DE": "Germany", "GB": "United Kingdom"},
items=[
DomainDashboardBanItem(
ip="1.1.1.1",
jail="sshd",
banned_at="2026-04-28T07:00:00+00:00",
ban_count=1,
origin="selfblock",
),
],
total=18,
)
result = map_domain_bans_by_country_to_response(domain_data)
assert result.countries == {"US": 10, "DE": 5, "GB": 3}
assert result.country_names == {"US": "United States", "DE": "Germany", "GB": "United Kingdom"}
assert result.total == 18
assert len(result.bans) == 1
class TestBanTrendMapper:
"""Test mapping from DomainBanTrend to BanTrendResponse."""
def test_maps_buckets_and_size_label(self) -> None:
"""Buckets and size label are correctly mapped."""
domain_trend = DomainBanTrend(
buckets=[
DomainBanTrendBucket(timestamp="2026-04-28T00:00:00+00:00", count=10),
DomainBanTrendBucket(timestamp="2026-04-28T01:00:00+00:00", count=15),
],
bucket_size="1h",
)
result = map_domain_ban_trend_to_response(domain_trend)
assert result.bucket_size == "1h"
assert len(result.buckets) == 2
assert result.buckets[0].timestamp == "2026-04-28T00:00:00+00:00"
assert result.buckets[0].count == 10
class TestBansByJailMapper:
"""Test mapping from DomainBansByJail to BansByJailResponse."""
def test_maps_jail_counts(self) -> None:
"""Jail counts are correctly mapped."""
domain_data = DomainBansByJail(
jails=[
DomainJailBanCount(jail="sshd", count=50),
DomainJailBanCount(jail="httpd", count=20),
],
total=70,
)
result = map_domain_bans_by_jail_to_response(domain_data)
assert result.total == 70
assert len(result.jails) == 2
assert result.jails[0].jail == "sshd"
assert result.jails[0].count == 50