"""Tests for views: CatalogZone list/detail/edit, CatalogZoneMember list/detail, SeenTransferClient list/detail — auth gate and context.""" import pytest from django.test import Client from django.contrib.auth import get_user_model @pytest.fixture def client(): return Client() @pytest.fixture def superuser(db): User = get_user_model() user = User(username="admin", email="admin@test.local", is_superuser=True) user.set_password("testpass") user.save() return user @pytest.fixture def regular_user(db): User = get_user_model() user = User(username="regular", email="reg@test.local") user.set_password("testpass") user.save() return user @pytest.mark.django_db class TestCatalogZoneMemberListView: def test_unauthenticated_redirects_to_login(self, client): resp = client.get("/plugins/dns-bridge/catalog-zone-members/") assert resp.status_code in (302, 403) def test_regular_user_forbidden(self, client, regular_user): client.login(username="regular", password="testpass") resp = client.get("/plugins/dns-bridge/catalog-zone-members/") assert resp.status_code in (302, 403) def test_superuser_can_access(self, client, superuser, make_zone): make_zone(name="member-list.test") client.login(username="admin", password="testpass") resp = client.get("/plugins/dns-bridge/catalog-zone-members/") assert resp.status_code == 200 def test_list_contains_members(self, client, superuser, make_zone): zone = make_zone(name="member-row.test") client.login(username="admin", password="testpass") resp = client.get("/plugins/dns-bridge/catalog-zone-members/") member_list = list(resp.context["table"].data) assert len(member_list) >= 1 m = next(m for m in member_list if m.zone_id == zone.id) assert m.name @pytest.mark.django_db class TestCatalogZoneMemberDetailView: def test_unauthenticated_redirects_to_login(self, client, make_zone): zone = make_zone(name="member-detail.test") from netbox_dns_bridge.models import CatalogZoneMember m = CatalogZoneMember.objects.get(zone=zone) resp = client.get(f"/plugins/dns-bridge/catalog-zone-members/{m.pk}/") assert resp.status_code in (302, 403) def test_regular_user_forbidden(self, client, regular_user, make_zone): zone = make_zone(name="member-detail-forbidden.test") from netbox_dns_bridge.models import CatalogZoneMember m = CatalogZoneMember.objects.get(zone=zone) client.login(username="regular", password="testpass") resp = client.get(f"/plugins/dns-bridge/catalog-zone-members/{m.pk}/") assert resp.status_code in (302, 403) def test_superuser_can_access_detail(self, client, superuser, make_zone): zone = make_zone(name="member-detail-get.test") from netbox_dns_bridge.models import CatalogZoneMember m = CatalogZoneMember.objects.get(zone=zone) client.login(username="admin", password="testpass") resp = client.get(f"/plugins/dns-bridge/catalog-zone-members/{m.pk}/") assert resp.status_code == 200 assert resp.context["object"].name == m.name @pytest.mark.django_db class TestCatalogZoneListView: def test_unauthenticated_redirects_to_login(self, client): resp = client.get("/plugins/dns-bridge/catalog-zones/") assert resp.status_code in (302, 403) def test_regular_user_forbidden(self, client, regular_user): client.login(username="regular", password="testpass") resp = client.get("/plugins/dns-bridge/catalog-zones/") assert resp.status_code in (302, 403) def test_superuser_can_access(self, client, superuser): client.login(username="admin", password="testpass") resp = client.get("/plugins/dns-bridge/catalog-zones/") assert resp.status_code == 200 def test_list_contains_catalog_zones(self, client, superuser, catz_serial, make_zone): zone = make_zone(name="ctx.test") client.login(username="admin", password="testpass") resp = client.get("/plugins/dns-bridge/catalog-zones/") cz_list = list(resp.context["table"].data) assert len(cz_list) >= 1 cz = next(c for c in cz_list if c.view_id == zone.view_id) assert cz.soa_serial == catz_serial def test_list_empty_when_no_catalog_zones(self, client, superuser): client.login(username="admin", password="testpass") resp = client.get("/plugins/dns-bridge/catalog-zones/") cz_list = list(resp.context["table"].data) assert cz_list == [] @pytest.mark.django_db class TestCatalogZoneEditView: def test_unauthenticated_redirects_to_login(self, client, make_view): view = make_view(name="edit-cz-view") from netbox_dns_bridge.models import CatalogZone cz = CatalogZone.objects.create(view=view) resp = client.get(f"/plugins/dns-bridge/catalog-zones/{cz.pk}/edit/") assert resp.status_code in (302, 403) def test_regular_user_forbidden(self, client, regular_user, make_view): view = make_view(name="edit-cz-view-forbidden") from netbox_dns_bridge.models import CatalogZone cz = CatalogZone.objects.create(view=view) client.login(username="regular", password="testpass") resp = client.get(f"/plugins/dns-bridge/catalog-zones/{cz.pk}/edit/") assert resp.status_code in (302, 403) def test_superuser_can_get_edit_form(self, client, superuser, make_view): view = make_view(name="edit-cz-view-get") from netbox_dns_bridge.models import CatalogZone cz = CatalogZone.objects.create(view=view) client.login(username="admin", password="testpass") resp = client.get(f"/plugins/dns-bridge/catalog-zones/{cz.pk}/edit/") assert resp.status_code == 200 def test_superuser_can_update_soa_fields(self, client, superuser, make_view): view = make_view(name="edit-cz-view-post") from netbox_dns_bridge.models import CatalogZone cz = CatalogZone.objects.create(view=view) client.login(username="admin", password="testpass") resp = client.post( f"/plugins/dns-bridge/catalog-zones/{cz.pk}/edit/", { "soa_serial": 100, "soa_refresh": 300, "soa_retry": 100, "soa_expire": 86400, "soa_minimum": 3600, }, ) cz.refresh_from_db() assert cz.soa_serial == 100 assert cz.soa_refresh == 300 assert cz.soa_retry == 100 assert cz.soa_expire == 86400 assert cz.soa_minimum == 3600 def test_no_create_route(self, client, superuser): client.login(username="admin", password="testpass") resp = client.get("/plugins/dns-bridge/catalog-zones/add/") assert resp.status_code == 404 def test_no_delete_route(self, client, superuser, make_view): view = make_view(name="edit-cz-view-delete") from netbox_dns_bridge.models import CatalogZone cz = CatalogZone.objects.create(view=view) client.login(username="admin", password="testpass") resp = client.get(f"/plugins/dns-bridge/catalog-zones/{cz.pk}/delete/") assert resp.status_code == 404 @pytest.mark.django_db class TestCatalogZoneDetailView: def test_unauthenticated_redirects_to_login(self, client, make_view): view = make_view(name="detail-cz-view") from netbox_dns_bridge.models import CatalogZone cz = CatalogZone.objects.create(view=view) resp = client.get(f"/plugins/dns-bridge/catalog-zones/{cz.pk}/") assert resp.status_code in (302, 403) def test_regular_user_forbidden(self, client, regular_user, make_view): view = make_view(name="detail-cz-view-forbidden") from netbox_dns_bridge.models import CatalogZone cz = CatalogZone.objects.create(view=view) client.login(username="regular", password="testpass") resp = client.get(f"/plugins/dns-bridge/catalog-zones/{cz.pk}/") assert resp.status_code in (302, 403) def test_superuser_can_access_detail(self, client, superuser, make_view): view = make_view(name="detail-cz-view-get") from netbox_dns_bridge.models import CatalogZone cz = CatalogZone.objects.create(view=view, soa_serial=42) client.login(username="admin", password="testpass") resp = client.get(f"/plugins/dns-bridge/catalog-zones/{cz.pk}/") assert resp.status_code == 200 assert resp.context["object"].soa_serial == 42 @pytest.mark.django_db class TestSeenTransferClientListView: def test_unauthenticated_redirects_to_login(self, client): resp = client.get("/plugins/dns-bridge/seen-transfer-clients/") assert resp.status_code in (302, 403) def test_regular_user_forbidden(self, client, regular_user): client.login(username="regular", password="testpass") resp = client.get("/plugins/dns-bridge/seen-transfer-clients/") assert resp.status_code in (302, 403) def test_superuser_can_access(self, client, superuser, make_view): from netbox_dns_bridge.models import SeenTransferClient from django.utils import timezone view = make_view(name="stc-list-view") SeenTransferClient.objects.create( source_ip="192.0.2.1", view=view, last_seen=timezone.now() ) client.login(username="admin", password="testpass") resp = client.get("/plugins/dns-bridge/seen-transfer-clients/") assert resp.status_code == 200 def test_list_contains_clients(self, client, superuser, make_view): from netbox_dns_bridge.models import SeenTransferClient from django.utils import timezone view = make_view(name="stc-list-row-view") SeenTransferClient.objects.create( source_ip="192.0.2.1", view=view, last_seen=timezone.now() ) client.login(username="admin", password="testpass") resp = client.get("/plugins/dns-bridge/seen-transfer-clients/") client_list = list(resp.context["table"].data) assert len(client_list) >= 1 assert client_list[0].source_ip == "192.0.2.1" @pytest.mark.django_db class TestSeenTransferClientDetailView: def test_unauthenticated_redirects_to_login(self, client, make_view): from netbox_dns_bridge.models import SeenTransferClient from django.utils import timezone view = make_view(name="stc-detail-view") c = SeenTransferClient.objects.create( source_ip="192.0.2.1", view=view, last_seen=timezone.now() ) resp = client.get(f"/plugins/dns-bridge/seen-transfer-clients/{c.pk}/") assert resp.status_code in (302, 403) def test_regular_user_forbidden(self, client, regular_user, make_view): from netbox_dns_bridge.models import SeenTransferClient from django.utils import timezone view = make_view(name="stc-detail-forbidden-view") c = SeenTransferClient.objects.create( source_ip="192.0.2.1", view=view, last_seen=timezone.now() ) client.login(username="regular", password="testpass") resp = client.get(f"/plugins/dns-bridge/seen-transfer-clients/{c.pk}/") assert resp.status_code in (302, 403) def test_superuser_can_access_detail(self, client, superuser, make_view): from netbox_dns_bridge.models import SeenTransferClient from django.utils import timezone view = make_view(name="stc-detail-get-view") c = SeenTransferClient.objects.create( source_ip="192.0.2.42", view=view, last_seen=timezone.now() ) client.login(username="admin", password="testpass") resp = client.get(f"/plugins/dns-bridge/seen-transfer-clients/{c.pk}/") assert resp.status_code == 200 assert resp.context["object"].source_ip == "192.0.2.42"