import datetime import os import sys import pytest from fastapi.testclient import TestClient sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) import api_server import cidr_collector as cc import db import formatters VALUES = ["10.0.0.0/23", "10.0.0.0/24", "10.0.1.5", "2001:db8::/32", "1.1.1.1"] def test_select_default_aggregate_and_version(): # По умолчанию вывод прежний: строки как есть, лексикографическая сортировка assert formatters.build_output(VALUES) == sorted(VALUES) assert formatters.build_output(VALUES, ip_version="6") == ["2001:db8::/32"] assert "2001:db8::/32" not in formatters.build_output(VALUES, ip_version="4") # Агрегация: /24 и 10.0.1.5 поглощены /23, одиночный IP печатается без /32 assert formatters.build_output(VALUES, aggregate=True) == ["1.1.1.1", "10.0.0.0/23", "2001:db8::/32"] @pytest.mark.parametrize("fmt,v4_line,v6_line", [ ("nftables", "add element inet ripe ripe_v4 {", "add element inet ripe ripe_v6 {"), ("mikrotik", "/ip firewall address-list add list=ripe address=10.0.0.0/23", "/ipv6 firewall address-list add list=ripe address=2001:db8::/32"), ("bird", "define RIPE_V4 = [", "define RIPE_V6 = ["), ("frr", "ip prefix-list ripe_v4 seq 10 permit 10.0.0.0/23", "ipv6 prefix-list ripe_v6 seq 5 permit 2001:db8::/32"), ]) def test_render_formats(fmt, v4_line, v6_line): out = formatters.build_output(VALUES, fmt, aggregate=True) assert v4_line in out and v6_line in out and out.endswith("\n") # Пустая версия пропускается only_v6 = formatters.build_output(VALUES, fmt, ip_version="6") assert v6_line in only_v6 and v4_line not in only_v6 def test_api_formats(tmp_path, monkeypatch): monkeypatch.setattr(cc, "DB_FILE", str(tmp_path / "ripe.db")) monkeypatch.setattr(cc, "DATA_FILE", str(tmp_path / "data.json")) monkeypatch.setattr(cc, "FQDN_DATA_FILE", str(tmp_path / "fqdn_data.json")) with db.session() as conn, db.transaction(conn): db.merge_source(conn, "asn", "1", {"10.0.0.0/23", "2001:db8::/32"}, datetime.datetime.now(), 90) client = TestClient(api_server.app) assert client.get("/addresses").json() == ["10.0.0.0/23", "2001:db8::/32"] resp = client.get("/addresses", params={"format": "mikrotik", "name": "tg"}) assert resp.headers["content-type"].startswith("text/plain") assert "list=tg address=10.0.0.0/23" in resp.text assert client.get("/addresses", params={"name": "bad name;"}).status_code == 422