Files
derp/tests/test_defang.py
user 9abf8dce64 feat: add !paste command and unit tests for 5 core plugins
Add cmd_paste to flaskpaste plugin (create paste, return URL).
Add test suites for encode, hash, defang, cidr, and dns plugins
(83 new test cases, 1093 total).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 16:54:18 +01:00

148 lines
4.2 KiB
Python

"""Tests for the defang/refang plugin."""
import asyncio
import importlib.util
import sys
from pathlib import Path
from derp.irc import Message
# plugins/ is not a Python package -- load the module from file path
_spec = importlib.util.spec_from_file_location(
"plugins.defang", Path(__file__).resolve().parent.parent / "plugins" / "defang.py",
)
_mod = importlib.util.module_from_spec(_spec)
sys.modules[_spec.name] = _mod
_spec.loader.exec_module(_mod)
from plugins.defang import ( # noqa: E402
_defang,
_refang,
cmd_defang,
cmd_refang,
)
# -- Helpers -----------------------------------------------------------------
class _FakeBot:
def __init__(self):
self.replied: list[str] = []
async def reply(self, message, text: str) -> None:
self.replied.append(text)
def _msg(text: str) -> Message:
return Message(
raw="", prefix="alice!~alice@host", nick="alice",
command="PRIVMSG", params=["#test", text], tags={},
)
# -- Pure function: _defang --------------------------------------------------
class TestDefangFunction:
def test_http_url(self):
result = _defang("http://evil.com")
assert "[://]" in result
def test_https_url(self):
result = _defang("https://evil.com/path")
assert "[://]" in result
def test_ftp_url(self):
result = _defang("ftp://files.evil.com")
assert "ftp[://]" in result
def test_ip_address(self):
assert _defang("192.168.1.1") == "192[.]168[.]1[.]1"
def test_path_dots_preserved(self):
result = _defang("http://evil.com/file.php?q=1")
assert "[://]" in result
assert "file.php" in result
def test_domain_only(self):
assert _defang("evil.com") == "evil[.]com"
# -- Pure function: _refang --------------------------------------------------
class TestRefangFunction:
def test_basic(self):
assert _refang("evil[.]com") == "evil.com"
def test_protocol(self):
assert _refang("http[://]evil[.]com") == "http://evil.com"
def test_hxxp(self):
assert _refang("hxxps[://]evil[.]com") == "https://evil.com"
def test_hXXp(self):
assert _refang("hXXps[://]evil[.]com") == "https://evil.com"
def test_at_sign(self):
assert _refang("user[at]evil[.]com") == "user@evil.com"
def test_at_uppercase(self):
assert _refang("user[AT]evil[.]com") == "user@evil.com"
# -- Roundtrip ---------------------------------------------------------------
class TestRoundtrip:
def test_ip(self):
original = "10.0.0.1"
defanged = _defang(original)
refanged = _refang(defanged)
assert refanged == original
def test_domain(self):
original = "evil.com"
defanged = _defang(original)
assert "[.]" in defanged
refanged = _refang(defanged)
assert refanged == original
def test_refang_hxxp(self):
"""Refang handles hxxp notation not produced by _defang."""
assert _refang("hxxps://evil[.]com") == "https://evil.com"
# -- Command: defang ---------------------------------------------------------
class TestCmdDefang:
def test_url(self):
bot = _FakeBot()
asyncio.run(cmd_defang(bot, _msg("!defang https://evil.com/path")))
assert "[://]" in bot.replied[0]
def test_ip(self):
bot = _FakeBot()
asyncio.run(cmd_defang(bot, _msg("!defang 192.168.1.1")))
assert bot.replied[0] == "192[.]168[.]1[.]1"
def test_missing_args(self):
bot = _FakeBot()
asyncio.run(cmd_defang(bot, _msg("!defang")))
assert "Usage" in bot.replied[0]
# -- Command: refang ---------------------------------------------------------
class TestCmdRefang:
def test_url(self):
bot = _FakeBot()
asyncio.run(cmd_refang(bot, _msg("!refang hxxps[://]evil[.]com")))
assert bot.replied[0] == "https://evil.com"
def test_ip(self):
bot = _FakeBot()
asyncio.run(cmd_refang(bot, _msg("!refang 10[.]0[.]0[.]1")))
assert bot.replied[0] == "10.0.0.1"
def test_missing_args(self):
bot = _FakeBot()
asyncio.run(cmd_refang(bot, _msg("!refang")))
assert "Usage" in bot.replied[0]