Files
derp/tests/test_hash.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

149 lines
4.7 KiB
Python

"""Tests for the hash/hashid plugin."""
import asyncio
import hashlib
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.hash", Path(__file__).resolve().parent.parent / "plugins" / "hash.py",
)
_mod = importlib.util.module_from_spec(_spec)
sys.modules[_spec.name] = _mod
_spec.loader.exec_module(_mod)
from plugins.hash import cmd_hash, cmd_hashid # noqa: E402
# -- 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={},
)
# -- Hash: all algorithms ---------------------------------------------------
class TestHashAllAlgos:
def test_default_shows_md5_sha1_sha256(self):
bot = _FakeBot()
asyncio.run(cmd_hash(bot, _msg("!hash hello")))
reply = bot.replied[0]
assert "md5:" in reply
assert "sha1:" in reply
assert "sha256:" in reply
def test_default_values_correct(self):
bot = _FakeBot()
asyncio.run(cmd_hash(bot, _msg("!hash hello")))
reply = bot.replied[0]
expected_md5 = hashlib.md5(b"hello").hexdigest()
expected_sha1 = hashlib.sha1(b"hello").hexdigest()
expected_sha256 = hashlib.sha256(b"hello").hexdigest()
assert expected_md5 in reply
assert expected_sha1 in reply
assert expected_sha256 in reply
class TestHashSpecificAlgo:
def test_md5(self):
bot = _FakeBot()
asyncio.run(cmd_hash(bot, _msg("!hash md5 hello")))
expected = hashlib.md5(b"hello").hexdigest()
assert f"md5: {expected}" == bot.replied[0]
def test_sha1(self):
bot = _FakeBot()
asyncio.run(cmd_hash(bot, _msg("!hash sha1 hello")))
expected = hashlib.sha1(b"hello").hexdigest()
assert f"sha1: {expected}" == bot.replied[0]
def test_sha256(self):
bot = _FakeBot()
asyncio.run(cmd_hash(bot, _msg("!hash sha256 hello")))
expected = hashlib.sha256(b"hello").hexdigest()
assert f"sha256: {expected}" == bot.replied[0]
def test_sha512(self):
bot = _FakeBot()
asyncio.run(cmd_hash(bot, _msg("!hash sha512 hello")))
expected = hashlib.sha512(b"hello").hexdigest()
assert f"sha512: {expected}" == bot.replied[0]
class TestHashUnknownAlgo:
def test_unknown_treated_as_text(self):
"""Unknown algo name is treated as part of the text to hash."""
bot = _FakeBot()
asyncio.run(cmd_hash(bot, _msg("!hash unknown hello")))
reply = bot.replied[0]
# "unknown hello" is hashed as plain text (no algo match)
expected_md5 = hashlib.md5(b"unknown hello").hexdigest()
assert expected_md5 in reply
class TestHashMissingArgs:
def test_no_args(self):
bot = _FakeBot()
asyncio.run(cmd_hash(bot, _msg("!hash")))
assert "Usage" in bot.replied[0]
# -- HashID ------------------------------------------------------------------
class TestHashIdPatterns:
def test_md5(self):
h = hashlib.md5(b"test").hexdigest()
bot = _FakeBot()
asyncio.run(cmd_hashid(bot, _msg(f"!hashid {h}")))
assert "MD5" in bot.replied[0]
def test_sha1(self):
h = hashlib.sha1(b"test").hexdigest()
bot = _FakeBot()
asyncio.run(cmd_hashid(bot, _msg(f"!hashid {h}")))
assert "SHA-1" in bot.replied[0]
def test_sha256(self):
h = hashlib.sha256(b"test").hexdigest()
bot = _FakeBot()
asyncio.run(cmd_hashid(bot, _msg(f"!hashid {h}")))
assert "SHA-256" in bot.replied[0]
def test_bcrypt(self):
bcrypt_hash = "$2b$12$LJ3m4ysXql6gVjLnEQKbN.ZRA/O.mTeDGVMnRqz7E2B0sq1pYG2oW"
bot = _FakeBot()
asyncio.run(cmd_hashid(bot, _msg(f"!hashid {bcrypt_hash}")))
assert "bcrypt" in bot.replied[0]
def test_mysql41(self):
mysql_hash = "*94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29"
bot = _FakeBot()
asyncio.run(cmd_hashid(bot, _msg(f"!hashid {mysql_hash}")))
assert "MySQL" in bot.replied[0]
def test_unknown(self):
bot = _FakeBot()
asyncio.run(cmd_hashid(bot, _msg("!hashid zzznotahash")))
assert "Unknown" in bot.replied[0]
class TestHashIdMissingArgs:
def test_no_args(self):
bot = _FakeBot()
asyncio.run(cmd_hashid(bot, _msg("!hashid")))
assert "Usage" in bot.replied[0]