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>
149 lines
4.7 KiB
Python
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]
|