Awesome IRC bot
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

165 lines
4.6 KiB

5 years ago
import os
import sys
import pytest
5 years ago
from threading import Thread
5 years ago
from random import randint
from pyircbot import PyIRCBot
5 years ago
from pyircbot.pyircbot import PrimitiveBot
from pyircbot.irccore import IRCEvent, UserPrefix
from unittest.mock import MagicMock
5 years ago
from tests.miniircd import Server as MiniIrcServer
5 years ago
sys.path.append(os.path.join(os.path.dirname(__file__), "../pyircbot/modules/"))
class FakeBaseBot(PrimitiveBot):
"""
Class that simulates a bot base class. You need to add mocks for any methods you expect called, beyond privmsg.
"""
def __init__(self, config):
super().__init__(config)
self.act_PRIVMSG = MagicMock()
5 years ago
self._modules = []
5 years ago
def feed_line(self, trailing, cmd="PRIVMSG", args=["#test"], sender=("chatter", "root", "cia.gov")):
"""
Feed a message into the bot.
"""
msg = IRCEvent(cmd,
args,
UserPrefix(*sender),
trailing)
for module_name, module in self.moduleInstances.items():# TODO dedupe this block across the various base classes
for hook in module.irchooks:
validation = hook.validator(msg, self)
if validation:
hook.method(msg, validation)
5 years ago
def closeAllModules(self):
for modname in self._modules:
self.unloadmodule(modname)
def loadmodule(self, module_name):
super().loadmodule(module_name)
self._modules.append(module_name)
def unloadmodule(self, module_name):
super().unloadmodule(module_name)
self._modules.remove(module_name)
5 years ago
@pytest.fixture
5 years ago
def fakebot(tmpdir):
5 years ago
# TODO copy data tree to isolated place so each fakebot() is isolated
5 years ago
os.mkdir(os.path.join(tmpdir, "data"))
bot = FakeBaseBot({"bot": {"datadir": tmpdir},
5 years ago
"module_configs": {}})
5 years ago
yield bot
5 years ago
bot.closeAllModules()
5 years ago
@pytest.fixture
def ircserver():
"""
Fixture providing an isolated IRC server.
:return: tuple of (port, server_object)
"""
port = randint(40000, 65000)
class IRCOptions(object):
channel_log_dir = None
chroot = None
daemon = None
debug = None
ipv6 = None
listen = "127.0.0.1"
log_count = 10
log_file = None
log_max_size = 10
motd = None
password = None
password_file = None
pid_file = None
ports = [port]
setuid = None
ssl_pem_file = None
state_dir = None
verbose = None
server = MiniIrcServer(IRCOptions)
server_t = Thread(target=server.start, daemon=True)
server_t.start()
yield port, server
server.stop()
5 years ago
@pytest.fixture
def livebot(ircserver, tmpdir):
port, server = ircserver
channel = "#test" + str(randint(100000, 1000000))
nick = "testbot" + str(randint(100000, 1000000))
config = {
"bot": {
"datadir": tmpdir,
"rpcbind": "0.0.0.0",
"rpcport": -1,
"usermodules": []
},
"connection": {
"servers": [
["localhost", port]
],
"force_ipv6": False,
"rate_limit": {
"rate_max": 5.0,
"rate_int": 1.1
}
},
"modules": [
"PingResponder",
"Services"
],
"module_configs": {
"Services": {
"user": {
"nick": [
nick,
nick + "_",
nick + "__"
],
"password": "nickservpassword",
"username": "pyircbot3",
"hostname": "pyircbot3.domain.com",
"realname": "pyircbot3"
},
"ident": {
"enable": "no",
"to": "nickserv",
"command": "identify %(password)s",
"ghost": "no",
"ghost_to": "nickserv",
"ghost_cmd": "ghost %(nick)s %(password)s"
},
"channels": [
channel
],
"privatechannels": {
"to": "chanserv",
"command": "invite %(channel)s",
"list": []
}
}
}
}
bot = PyIRCBot(config)
bot_t = Thread(target=bot.run, daemon=True)
# bot_t.start()
yield port, server, bot, bot_t, channel, nick
bot.kill(message="bye", forever=True)