netsleuth/tests/test_cli.py
Horizontal42 45ce7509d2
🧪 Add test file for cli.py (#21)
* Add initial test suite for cli.py

Co-authored-by: Horizontal42 <75383519+Horizontal42@users.noreply.github.com>

* drop redundant pytest-cov dep addition

---------

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-08-19 17:36:36 +03:00

110 lines
3.5 KiB
Python

import os
from pathlib import Path
from unittest.mock import MagicMock, patch
from netsleuth.cli import _dedupe, _os_timezone, parse_target
from netsleuth.models import Finding
def test_parse_target_asn():
assert parse_target("AS12345") == ("asn", "AS12345")
assert parse_target("as12345") == ("asn", "AS12345")
assert parse_target("12345") == ("asn", "AS12345")
assert parse_target(" AS12345 ") == ("asn", "AS12345")
def test_parse_target_ip():
assert parse_target("1.2.3.4") == ("ip", "1.2.3.4")
assert parse_target("2001:db8::1") == ("ip", "2001:db8::1")
assert parse_target(" 1.2.3.4 ") == ("ip", "1.2.3.4")
def test_parse_target_domain():
assert parse_target("example.com") == ("domain", "example.com")
assert parse_target("foo-bar.baz") == ("domain", "foo-bar.baz")
assert parse_target(" example.com ") == ("domain", "example.com")
def test_dedupe_empty():
assert _dedupe([]) == []
def test_dedupe_unique():
findings = [
Finding(id="f1", severity="info", title="1", detail="1"),
Finding(id="f2", severity="info", title="2", detail="2"),
Finding(id="f3", severity="info", title="3", detail="3"),
]
assert _dedupe(findings) == findings
def test_dedupe_duplicates():
f1 = Finding(id="f1", severity="info", title="1", detail="1")
f2 = Finding(id="f2", severity="info", title="2", detail="2")
f1_dup = Finding(id="f1", severity="warn", title="dup", detail="dup")
findings = [f1, f2, f1_dup, f1, f2]
deduped = _dedupe(findings)
assert len(deduped) == 2
assert deduped[0] is f1
assert deduped[1] is f2
def test_os_timezone_from_env(monkeypatch):
monkeypatch.setenv("TZ", "America/New_York")
assert _os_timezone() == "America/New_York"
@patch("netsleuth.cli.Path")
def test_os_timezone_from_localtime_symlink(mock_path, monkeypatch):
monkeypatch.delenv("TZ", raising=False)
mock_localtime = MagicMock()
mock_localtime.is_symlink.return_value = True
mock_localtime.readlink.return_value = Path("/usr/share/zoneinfo/Europe/London")
def side_effect(path, *args, **kwargs):
if str(path) == "/etc/localtime":
return mock_localtime
return MagicMock()
mock_path.side_effect = side_effect
assert _os_timezone() == "Europe/London"
@patch("netsleuth.cli.Path")
def test_os_timezone_from_timezone_file(mock_path, monkeypatch):
monkeypatch.delenv("TZ", raising=False)
mock_localtime = MagicMock()
mock_localtime.is_symlink.return_value = False
mock_timezone = MagicMock()
mock_timezone.read_text.return_value = "Asia/Tokyo\n"
def side_effect(path, *args, **kwargs):
if str(path) == "/etc/localtime":
return mock_localtime
if str(path) == "/etc/timezone":
return mock_timezone
return MagicMock()
mock_path.side_effect = side_effect
assert _os_timezone() == "Asia/Tokyo"
@patch("netsleuth.cli.Path")
def test_os_timezone_none(mock_path, monkeypatch):
monkeypatch.delenv("TZ", raising=False)
mock_localtime = MagicMock()
mock_localtime.is_symlink.return_value = False
mock_timezone = MagicMock()
mock_timezone.read_text.side_effect = OSError("File not found")
def side_effect(path, *args, **kwargs):
if str(path) == "/etc/localtime":
return mock_localtime
if str(path) == "/etc/timezone":
return mock_timezone
return MagicMock()
mock_path.side_effect = side_effect
assert _os_timezone() is None