class EmptyTests(unittest.TestCase): def setUp(self): self.engine = Engine(mouth=Queue()) self.engine.configure() self.engine.shell = Shell(engine=self.engine) self.bot = MyBot(engine=self.engine) def tearDown(self): collected = gc.collect() if collected: logging.info("Garbage collector: collected %d objects." % (collected)) def test_init(self): logging.info('***** init') c = Empty(self.engine) self.assertEqual(c.keyword, u'*empty') self.assertEqual(c.information_message, u'Handle empty command') self.assertEqual(c.usage_message, None) self.assertTrue(c.is_hidden) def test_execute(self): logging.info('***** execute') self.engine.shell.load_command('shellbot.commands.help') c = Empty(self.engine) c.execute(self.bot) self.assertEqual( self.engine.mouth.get().text, u'Available commands:\nhelp - Show commands and usage') with self.assertRaises(Exception): print(self.engine.mouth.get_nowait()) c = Empty(self.engine) self.engine.shell._commands = {} c.execute(self.bot) self.assertEqual(self.engine.mouth.get().text, u'No help command has been found.') with self.assertRaises(Exception): print(self.engine.mouth.get_nowait())
class UploadTests(unittest.TestCase): def setUp(self): self.engine = Engine(mouth=Queue()) self.engine.configure() self.engine.shell = Shell(engine=self.engine) self.bot = MyBot(engine=self.engine) def tearDown(self): del self.bot del self.engine collected = gc.collect() if collected: logging.info("Garbage collector: collected %d objects." % (collected)) def test_init(self): logging.info('***** init') c = Upload(self.engine) self.assertEqual(c.keyword, u'*upload') self.assertEqual(c.information_message, u'Handle file upload') self.assertEqual(c.usage_message, None) self.assertTrue(c.is_hidden) def test_execute(self): logging.info('***** execute') c = Upload(self.engine) c.execute(self.bot, url='http://from/here', attachment='picture.png') self.assertEqual(self.engine.mouth.get().text, u'Thank you for the information shared!') with self.assertRaises(Exception): print(self.engine.mouth.get_nowait())
""" import logging from multiprocessing import Process, Queue import os from shellbot import Engine, Context from shellbot.updaters import FileUpdater class UpdaterFactory(object): # create one updater per group channel def get_updater(self, id): return FileUpdater(path='./updater-{}.log'.format(id)) if __name__ == '__main__': Context.set_logger() engine = Engine( # use Cisco Spark and setup audit environment type='spark', command='shellbot.commands.audit', updater_factory=UpdaterFactory()) os.environ['CHAT_ROOM_TITLE'] = 'Audit tutorial' engine.configure() # ensure all components are ready engine.bond(reset=True) # create a group channel for this example engine.run() # until Ctl-C engine.dispose() # delete the initial group channel
direct_channel = self.engine.space.get_by_person(received.actor_label) if direct_channel: direct_bot = self.engine.get_bot(direct_channel.id) if direct_bot.machine and not direct_bot.machine.is_running: direct_bot.machine.restart() def on_leave(self, received): print("LEAVE: {}".format(received)) bot = self.engine.get_bot(received.channel_id) bot.say(u"Bye bye '{}', we will miss you in '{}'".format( received.actor_label, bot.title)) if __name__ == '__main__': Context.set_logger() engine = Engine(type='spark', command='shellbot.commands.input', machine_factory=MyFactory()) os.environ['CHAT_ROOM_TITLE'] = '*dummy' engine.configure() handler = Handler(engine) engine.register('enter', handler) engine.register('exit', handler) engine.register('join', handler) engine.register('leave', handler) engine.run()
class EngineTests(unittest.TestCase): def setUp(self): self.context = Context() self.engine = Engine(context=self.context, mouth=Queue()) self.space = LocalSpace(context=self.context) self.engine.space = self.space def tearDown(self): del self.space del self.engine del self.context collected = gc.collect() if collected: logging.info("Garbage collector: collected %d objects." % (collected)) def test_init(self): logging.info('*** init ***') engine = Engine(context=self.context) self.assertEqual(engine.context, self.context) self.assertTrue(engine.mouth is None) self.assertTrue(engine.speaker is not None) self.assertTrue(engine.ears is None) self.assertTrue(engine.listener is not None) self.assertTrue(engine.fan is None) self.assertTrue(engine.observer is not None) self.assertTrue(engine.registered is not None) self.assertEqual(engine.bots, {}) self.assertFalse(engine.space is None) self.assertTrue(engine.server is None) self.assertTrue(engine.shell is not None) self.assertEqual(engine.driver, ShellBot) self.assertEqual(engine.machine_factory, None) self.assertEqual(engine.updater_factory, None) del engine engine = Engine(context=self.context, type='local', mouth='m', ears='e', fan='f') self.assertEqual(engine.context, self.context) self.assertEqual(engine.mouth, 'm') self.assertTrue(engine.speaker is not None) self.assertEqual(engine.ears, 'e') self.assertTrue(engine.listener is not None) self.assertEqual(engine.fan, 'f') self.assertTrue(engine.observer is not None) self.assertTrue(engine.registered is not None) self.assertEqual(engine.bots, {}) self.assertTrue(engine.space is not None) self.assertTrue(engine.server is None) self.assertTrue(engine.shell is not None) self.assertEqual(engine.driver, ShellBot) self.assertEqual(engine.machine_factory, None) self.assertEqual(engine.updater_factory, None) del engine engine = Engine(context=self.context, space=self.space, mouth='m', ears='e', fan='f') self.assertEqual(engine.context, self.context) self.assertEqual(engine.mouth, 'm') self.assertTrue(engine.speaker is not None) self.assertEqual(engine.ears, 'e') self.assertTrue(engine.listener is not None) self.assertEqual(engine.fan, 'f') self.assertTrue(engine.observer is not None) self.assertTrue(engine.registered is not None) self.assertEqual(engine.bots, {}) self.assertEqual(engine.space, self.space) self.assertTrue(engine.server is None) self.assertTrue(engine.shell is not None) self.assertEqual(engine.driver, ShellBot) self.assertEqual(engine.machine_factory, None) self.assertEqual(engine.updater_factory, None) del engine engine = Engine( context=self.context, driver=FakeBot, machine_factory=MachineFactory, updater_factory=MyUpdaterFactory, ) self.assertEqual(engine.context, self.context) self.assertEqual(engine.mouth, None) self.assertTrue(engine.speaker is not None) self.assertEqual(engine.ears, None) self.assertTrue(engine.listener is not None) self.assertTrue(engine.fan is None) self.assertTrue(engine.observer is not None) self.assertTrue(engine.registered is not None) self.assertEqual(engine.bots, {}) self.assertTrue(engine.space is not None) self.assertTrue(engine.server is None) self.assertTrue(engine.shell is not None) self.assertEqual(engine.driver, FakeBot) self.assertEqual(engine.machine_factory, MachineFactory) self.assertEqual(engine.updater_factory, MyUpdaterFactory) self.context.apply({ 'bot': { 'name': 'testy', 'version': '17.4.1' }, }) engine = Engine(context=self.context) self.assertEqual(engine.name, 'testy') self.assertEqual(engine.version, '17.4.1') del engine def test_configure(self): logging.info('*** configure ***') self.engine.configure({}) self.assertEqual(self.engine.space.ears, self.engine.ears) self.assertTrue(self.engine.list_factory is not None) self.engine.context.clear() settings = { 'bot': { 'on_enter': 'Hello!', 'on_exit': 'Bye!', }, 'localized': { 'hello world': "What'up, Doc?", 'another string': 'Bye!', }, 'space': { 'title': 'space name', 'participants': ['*****@*****.**'], }, 'server': { 'url': 'http://to.no.where', 'hook': '/hook', 'binding': '0.0.0.0', 'port': 8080, }, } self.engine.configure(settings) self.assertEqual(self.engine.get('bot.on_enter'), 'Hello!') self.assertEqual(self.engine.get('bot.on_exit'), 'Bye!') self.assertEqual(self.engine.get('space.title'), 'space name') self.assertEqual(self.engine.get('space.participants'), ['*****@*****.**']) self.assertEqual(self.engine.get('server.url'), 'http://to.no.where') self.assertEqual(self.engine.get('server.hook'), '/hook') self.assertEqual(_('hello world'), "What'up, Doc?") self.assertEqual(_('not localized'), 'not localized') self.engine.context.clear() self.engine.configure_from_path( os.path.join(os.path.dirname(os.path.abspath(__file__)), 'test_settings', 'regular.yaml')) self.assertEqual(self.engine.get('bot.on_enter'), 'How can I help you?') self.assertEqual(self.engine.get('bot.on_exit'), 'Bye for now') self.assertEqual(self.engine.get('space.title'), 'Support channel') self.assertEqual(self.engine.get('space.participants'), ['*****@*****.**', '*****@*****.**']) self.assertEqual(self.engine.get('server.url'), None) self.assertEqual(self.engine.get('server.hook'), None) self.assertEqual(self.engine.get('server.binding'), None) self.assertEqual(self.engine.get('server.port'), None) items = [x for x in self.engine.list_factory.get_list('SupportTeam')] self.assertEqual(items, ['*****@*****.**', '*****@*****.**']) items = [x for x in self.engine.list_factory.get_list('*unknown*list')] self.assertEqual(items, []) names = self.engine.list_factory.list_commands() self.assertEqual(sorted(names), ['SupportTeam']) def test_configuration_2(self): logging.info('*** configure 2 ***') settings = { 'bot': { 'on_enter': 'Hello!', 'on_exit': 'Bye!', }, 'space': { 'title': 'Support channel', }, 'server': { 'url': 'http://to.nowhere/', 'trigger': '/trigger', 'hook': '/hook', 'binding': '0.0.0.0', 'port': 8080, }, } clear_env('CHANNEL_DEFAULT_PARTICIPANTS') context = Context(settings) engine = Engine(context=context, configure=True) self.assertEqual(engine.get('bot.on_enter'), 'Hello!') self.assertEqual(engine.get('bot.on_exit'), 'Bye!') self.assertEqual(engine.get('space.title'), 'Support channel') self.assertEqual(engine.get('space.participants'), None) self.assertEqual(engine.get('server.url'), 'http://to.nowhere/') self.assertEqual(engine.get('server.hook'), '/hook') self.assertEqual(engine.get('server.trigger'), '/trigger') self.assertEqual(engine.get('server.binding'), None) self.assertEqual(engine.get('server.port'), 8080) def test_configure_default(self): logging.info('*** configure with default values ***') clear_env("BOT_BANNER_TEXT") clear_env("BOT_BANNER_CONTENT") clear_env("BOT_BANNER_FILE") clear_env("BOT_ON_ENTER") clear_env("BOT_ON_EXIT") clear_env("CHAT_ROOM_TITLE") clear_env("CHANNEL_DEFAULT_PARTICIPANTS") clear_env("CISCO_SPARK_BOT_TOKEN") clear_env("SERVER_URL") self.engine.configure() # logging.debug(self.engine.context.values) self.assertEqual(self.engine.get('bot.banner.text'), None) self.assertEqual(self.engine.get('bot.banner.content'), None) self.assertEqual(self.engine.get('bot.banner.file'), None) self.assertEqual(self.engine.get('bot.on_enter'), None) self.assertEqual(self.engine.get('bot.on_exit'), None) self.assertEqual(self.engine.get('space.title'), 'Collaboration space') self.assertEqual(self.engine.get('space.participants'), None) self.assertEqual(self.engine.get('space.unknown'), None) self.assertEqual(self.engine.get('server.url'), '$SERVER_URL') self.assertEqual(self.engine.get('server.hook'), '/hook') self.assertEqual(self.engine.get('server.binding'), None) self.assertEqual(self.engine.get('server.port'), 8080) self.assertEqual(self.engine.space.ears, self.engine.ears) self.assertTrue(self.engine.bus is not None) self.assertTrue(self.engine.publisher is not None) def test_configure_environment(self): logging.info('*** configure from the environment ***') os.environ["BOT_BANNER_TEXT"] = 'some text' os.environ["BOT_BANNER_CONTENT"] = 'some content' os.environ["BOT_BANNER_FILE"] = 'some link' os.environ["BOT_ON_ENTER"] = 'Hello!' os.environ["BOT_ON_EXIT"] = 'Bye!' os.environ["CHAT_ROOM_TITLE"] = 'Support channel' os.environ["CHANNEL_DEFAULT_PARTICIPANTS"] = '*****@*****.**' os.environ["CISCO_SPARK_BOT_TOKEN"] = '*token' os.environ["SERVER_URL"] = 'http://to.nowhere/' self.engine.configure() # logging.debug(self.engine.context.values) self.assertEqual(self.engine.get('bot.banner.text'), 'some text') self.assertEqual(self.engine.get('bot.banner.content'), 'some content') self.assertEqual(self.engine.get('bot.banner.file'), 'some link') self.assertEqual(self.engine.get('bot.on_enter'), 'Hello!') self.assertEqual(self.engine.get('bot.on_exit'), 'Bye!') self.assertEqual(self.engine.get('space.title'), 'Support channel') self.assertEqual(self.engine.get('space.participants'), '*****@*****.**') self.assertEqual(self.engine.get('space.unknown'), None) self.assertEqual(self.engine.get('server.url'), '$SERVER_URL') self.assertEqual(self.engine.get('server.hook'), '/hook') self.assertEqual(self.engine.get('server.binding'), None) self.assertEqual(self.engine.get('server.port'), 8080) def test_get(self): logging.info('*** get ***') os.environ["BOT_ON_ENTER"] = 'Hello!' os.environ["BOT_ON_EXIT"] = 'Bye!' os.environ["CHAT_ROOM_TITLE"] = 'Support channel' os.environ["CHANNEL_DEFAULT_PARTICIPANTS"] = '*****@*****.**' os.environ["CISCO_SPARK_BOT_TOKEN"] = '*token' os.environ["SERVER_URL"] = 'http://to.nowhere/' settings = { 'bot': { 'on_enter': 'Hello!', 'on_exit': 'Bye!', }, 'space': { 'title': '$CHAT_ROOM_TITLE', }, 'server': { 'url': '$SERVER_URL', 'hook': '/hook', 'binding': '0.0.0.0', 'port': 8080, }, } self.engine.configure(settings=settings) self.assertEqual(self.engine.get('bot.on_enter'), 'Hello!') self.assertEqual(self.engine.get('bot.on_exit'), 'Bye!') self.assertEqual(self.engine.get('space.title'), 'Support channel') self.assertEqual(self.engine.get('space.participants'), '*****@*****.**') self.assertEqual(self.engine.get('space.unknown'), None) self.assertEqual(self.engine.get('server.url'), 'http://to.nowhere/') self.assertEqual(self.engine.get('server.hook'), '/hook') self.assertEqual(self.engine.get('server.binding'), None) self.assertEqual(self.engine.get('server.port'), 8080) def test_set(self): logging.info('*** set ***') self.engine.set('hello', 'world') self.assertEqual(self.engine.get('hello'), 'world') self.assertEqual(self.engine.get(u'hello'), 'world') self.engine.set('hello', u'wôrld') self.assertEqual(self.engine.get('hello'), u'wôrld') self.engine.set(u'hello', u'wôrld') self.assertEqual(self.engine.get(u'hello'), u'wôrld') def test_name(self): logging.info('*** name ***') self.assertEqual(self.engine.name, 'Shelly') def test_version(self): logging.info('*** version ***') self.assertEqual(self.engine.version, '*unknown*') def test_register(self): logging.info('*** register ***') with self.assertRaises(AttributeError): self.engine.register('*unknown*event', lambda: 'ok') with self.assertRaises(AttributeError): self.engine.register('bond', lambda: 'ok') with self.assertRaises(AttributeError): self.engine.register('dispose', lambda: 'ok') counter = MyCounter('counter #1') with self.assertRaises(AssertionError): self.engine.register(None, counter) with self.assertRaises(AssertionError): self.engine.register('', counter) with self.assertRaises(AssertionError): self.engine.register(1.2, counter) self.engine.register('bond', counter) self.engine.register('dispose', counter) with self.assertRaises(AttributeError): self.engine.register('start', counter) with self.assertRaises(AttributeError): self.engine.register('stop', counter) with self.assertRaises(AttributeError): self.engine.register('*unknown*event', counter) self.engine.register('bond', MyCounter('counter #2')) class AllEvents(object): def on_bond(self, bot): pass def on_dispose(self): pass def on_start(self): pass def on_stop(self): pass def on_message(self): pass def on_join(self): pass def on_leave(self): pass def on_enter(self): pass def on_exit(self): pass def on_inbound(self): pass def on_some_custom_event(self): pass all_events = AllEvents() self.engine.register('bond', all_events) self.engine.register('dispose', all_events) self.engine.register('start', all_events) self.engine.register('stop', all_events) self.engine.register('message', all_events) self.engine.register('join', all_events) self.engine.register('leave', all_events) self.engine.register('enter', all_events) self.engine.register('exit', all_events) self.engine.register('inbound', all_events) self.engine.register('some_custom_event', all_events) self.assertEqual(len(self.engine.registered['bond']), 3) self.assertEqual(len(self.engine.registered['dispose']), 2) self.assertEqual(len(self.engine.registered['start']), 1) self.assertEqual(len(self.engine.registered['stop']), 1) self.assertEqual(len(self.engine.registered['message']), 1) self.assertEqual(len(self.engine.registered['join']), 1) self.assertEqual(len(self.engine.registered['leave']), 1) self.assertEqual(len(self.engine.registered['enter']), 1) self.assertEqual(len(self.engine.registered['exit']), 1) self.assertEqual(len(self.engine.registered['inbound']), 1) self.assertEqual(len(self.engine.registered['some_custom_event']), 1) def test_dispatch(self): logging.info('*** dispatch ***') counter = MyCounter('counter #1') self.engine.register('bond', counter) self.engine.register('dispose', counter) self.engine.register('bond', MyCounter('counter #2')) self.engine.register('dispose', MyCounter('counter #3')) class AllEvents(object): def __init__(self): self.events = [] def on_bond(self, bot): self.events.append('bond') def on_dispose(self): self.events.append('dispose') def on_start(self): self.events.append('start') def on_stop(self): self.events.append('stop') def on_message(self, received): assert received == '*void' self.events.append('message') def on_join(self, received): assert received == '*void' self.events.append('join') def on_leave(self, received): assert received == '*void' self.events.append('leave') def on_enter(self, received): assert received == '*void' self.events.append('enter') def on_exit(self, received): assert received == '*void' self.events.append('exit') def on_inbound(self, received): assert received == '*void' self.events.append('inbound') def on_some_custom_event(self, data): assert data == '*data' self.events.append('some_custom_event') all_events = AllEvents() self.engine.register('bond', all_events) self.engine.register('dispose', all_events) self.engine.register('start', all_events) self.engine.register('stop', all_events) self.engine.register('message', all_events) self.engine.register('join', all_events) self.engine.register('leave', all_events) self.engine.register('enter', all_events) self.engine.register('exit', all_events) self.engine.register('inbound', all_events) self.engine.register('some_custom_event', all_events) self.engine.dispatch('bond', bot='*dummy') self.engine.dispatch('dispose') self.engine.dispatch('start') self.engine.dispatch('stop') self.engine.dispatch('message', received='*void') self.engine.dispatch('join', received='*void') self.engine.dispatch('leave', received='*void') self.engine.dispatch('enter', received='*void') self.engine.dispatch('exit', received='*void') self.engine.dispatch('inbound', received='*void') self.engine.dispatch('some_custom_event', data='*data') with self.assertRaises(AssertionError): self.engine.dispatch('*unknown*event') self.assertEqual(counter.count, 2) self.assertEqual(all_events.events, [ 'bond', 'dispose', 'start', 'stop', 'message', 'join', 'leave', 'enter', 'exit', 'inbound', 'some_custom_event' ]) def test_load_commands(self): logging.info('*** load_commands ***') with mock.patch.object(self.engine.shell, 'load_commands', return_value=None) as mocked: self.engine.load_commands(['a', 'b', 'c', 'd']) mocked.assert_called_with(['a', 'b', 'c', 'd']) def test_load_command(self): logging.info('*** load_command ***') with mock.patch.object(self.engine.shell, 'load_command', return_value=None) as mocked: self.engine.load_command('a') mocked.assert_called_with('a') def test_hook(self): logging.info('*** hook ***') self.context.set('server.url', 'http://here.you.go:123') server = mock.Mock() with mock.patch.object(self.engine.space, 'register', return_value=None) as mocked: self.engine.hook(server=server) self.assertFalse(mocked.called) self.context.set('server.binding', '0.0.0.0') self.engine.hook(server=server) mocked.assert_called_with(hook_url='http://here.you.go:123/hook') def test_get_hook(self): logging.info('*** get_hook ***') self.context.set('server.url', 'http://here.you.go:123') self.assertEqual(self.engine.get_hook(), self.engine.space.webhook) def test_run(self): logging.info('*** run ***') engine = Engine(context=self.context) engine.space = LocalSpace(context=self.context) engine.start = mock.Mock() engine.space.run = mock.Mock() engine.run() self.assertTrue(engine.start.called) self.assertTrue(engine.space.run.called) class MyServer(object): def __init__(self, engine): self.engine = engine def add_route(self, route, **kwargs): pass def run(self): self.engine.set("has_been_ran", True) server = MyServer(engine=engine) engine.run(server=server) self.assertTrue(engine.get("has_been_ran")) def test_start(self): logging.info('*** start ***') engine = Engine(context=self.context) engine.space = LocalSpace(context=self.context) engine.start_processes = mock.Mock() engine.on_start = mock.Mock() engine.start() self.assertTrue(engine.ears is not None) self.assertTrue(engine.mouth is not None) self.assertTrue(engine.start_processes.called) self.assertTrue(engine.on_start.called) def test_static(self): logging.info('*** static test ***') self.engine.configure() self.context.set('bus.address', 'tcp://127.0.0.1:6666') self.engine.listener.DEFER_DURATION = 0.0 self.engine.publisher.DEFER_DURATION = 0.0 self.engine.start() self.engine.stop() self.assertEqual(self.engine.get('listener.counter', 0), 0) self.assertEqual(self.engine.get('speaker.counter', 0), 0) def test_bond(self): logging.info("*** bond") self.space.delete = mock.Mock() channel = self.engine.bond(title=None) self.assertEqual(channel.id, '*local') self.assertEqual(channel.title, 'Collaboration space') channel = self.engine.bond(title='') self.assertEqual(channel.id, '*local') self.assertEqual(channel.title, 'Collaboration space') channel = self.engine.bond(title='hello world') self.assertEqual(channel.id, '*local') self.assertEqual(channel.title, 'hello world') self.assertFalse(self.space.delete.called) channel = self.engine.bond(reset=True) self.assertTrue(self.space.delete.called) self.space.add_participants = mock.Mock() self.engine.dispatch = mock.Mock() with mock.patch.object(self.space, 'get_by_title', return_value=None) as mocked: self.engine.bond( title='my title', participants=['c', 'd'], ) mocked.assert_called_with(title='my title') self.space.add_participants.assert_called_with(id='*local', persons=['c', 'd']) self.space.configure( settings={ 'space': { 'title': 'Another title', 'participants': ['*****@*****.**', '*****@*****.**'], } }) with mock.patch.object(self.space, 'get_by_title', return_value=None) as mocked: self.engine.bond() mocked.assert_called_with(title='Another title') self.space.add_participants.assert_called_with( id='*local', persons=['*****@*****.**', '*****@*****.**']) def test_enumerate_bots(self): logging.info('*** enumerate_bots ***') self.engine.bots = { '123': FakeBot(self.engine, '123'), '456': FakeBot(self.engine, '456'), '789': FakeBot(self.engine, '789'), } for bot in self.engine.enumerate_bots(): self.assertTrue(bot.id in ['123', '456', '789']) def test_get_bot(self): logging.info('*** get_bot ***') self.engine.bots = { '123': FakeBot(self.engine, '123'), '456': FakeBot(self.engine, '456'), '789': FakeBot(self.engine, '789'), } bot = self.engine.get_bot('123') self.assertEqual(bot.id, '123') self.assertEqual(bot, self.engine.bots['123']) bot = self.engine.get_bot('456') self.assertEqual(bot.id, '456') self.assertEqual(bot, self.engine.bots['456']) bot = self.engine.get_bot('789') self.assertEqual(bot.id, '789') self.assertEqual(bot, self.engine.bots['789']) with mock.patch.object(self.engine, 'build_bot', return_value=FakeBot(self.engine, '*bot')) as mocked: bot = self.engine.get_bot() self.assertEqual(bot.id, '*bot') self.assertTrue('*bot' in self.engine.bots.keys()) def test_build_bot(self): logging.info('*** build_bot ***') self.engine.context.apply(self.engine.DEFAULT_SETTINGS) self.engine.bots = {} bot = self.engine.build_bot('123', FakeBot) self.assertEqual(bot.id, '123') bot.store.remember('a', 'b') self.assertEqual(bot.store.recall('a'), 'b') bot = self.engine.build_bot('456', FakeBot) self.assertEqual(bot.id, '456') bot.store.remember('c', 'd') self.assertEqual(bot.store.recall('a'), None) self.assertEqual(bot.store.recall('c'), 'd') bot = self.engine.build_bot('789', FakeBot) self.assertEqual(bot.id, '789') bot.store.remember('e', 'f') self.assertEqual(bot.store.recall('a'), None) self.assertEqual(bot.store.recall('c'), None) self.assertEqual(bot.store.recall('e'), 'f') def test_on_build(self): logging.info('*** on_build ***') bot = ShellBot(engine=self.engine) self.engine.on_build(bot) def test_build_store(self): logging.info('*** build_store ***') store_1 = self.engine.build_store('123') store_1.append('names', 'Alice') store_1.append('names', 'Bob') self.assertEqual(store_1.recall('names'), ['Alice', 'Bob']) store_2 = self.engine.build_store('456') store_2.append('names', 'Chloe') store_2.append('names', 'David') self.assertEqual(store_2.recall('names'), ['Chloe', 'David']) self.assertEqual(store_1.recall('names'), ['Alice', 'Bob']) store_2.forget() self.assertEqual(store_1.recall('names'), ['Alice', 'Bob']) self.assertEqual(store_2.recall('names'), None) def test_initialize_store(self): logging.info('*** initialize_store ***') settings = {'bot.store': {'planets': ['Uranus', 'Mercury']}} self.engine.context.apply(settings) print(self.engine.get('bot.store')) bot = self.engine.build_bot('123', FakeBot) self.assertEqual(bot.store.recall('planets'), ['Uranus', 'Mercury']) def test_build_machine(self): logging.info('*** build_machine ***') bot = ShellBot(engine=self.engine) machine = self.engine.build_machine(bot) previous = self.engine.machine_factory self.engine.machine_factory = MachineFactory( module='shellbot.machines.base', name='Machine') machine = self.engine.build_machine(bot) self.engine.machine_factory = previous def test_build_updater(self): logging.info('*** build_updater ***') updater = self.engine.build_updater('*id') self.assertEqual(updater, None) self.engine.updater_factory = MyUpdaterFactory() updater = self.engine.build_updater('*id') self.assertEqual(updater.id, '*id')
class DefaultTests(unittest.TestCase): def setUp(self): self.context = Context() self.engine = Engine(context=self.context, mouth=Queue()) self.engine.configure() self.bot = Bot(engine=self.engine) def tearDown(self): del self.bot del self.engine del self.context collected = gc.collect() if collected: logging.info("Garbage collector: collected %d objects." % (collected)) def test_init(self): logging.info("***** init") c = Default(self.engine) self.assertEqual(c.keyword, u'*default') self.assertEqual(c.information_message, u'Handle unmatched commands') self.assertEqual(c.usage_message, None) self.assertTrue(c.is_hidden) def test_execute_unknown(self): logging.info("***** execute unknown") c = Default(self.engine) c.execute(self.bot, '*unknown*') self.assertEqual(self.engine.mouth.get().text, u"Sorry, I do not know how to handle '*unknown*'") with self.assertRaises(Exception): self.engine.mouth.get_nowait() def test_execute_named_list(self): logging.info("***** execute named list") self.engine.configure_from_path( os.path.join( os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'test_settings', 'regular.yaml')) c = Default(self.engine) c.execute(self.bot, 'The Famous Four') # as_command not set self.assertEqual( self.engine.mouth.get().text, u"Sorry, I do not know how to handle 'The Famous Four'") with self.assertRaises(Exception): self.engine.mouth.get_nowait() class MyChannel(object): is_direct = True self.bot.channel = MyChannel() c.execute(self.bot, 'SupportTeam') # as_command in direct channel self.assertEqual(self.engine.mouth.get().text, u"Sorry, I do not know how to handle 'SupportTeam'") with self.assertRaises(Exception): self.engine.mouth.get_nowait() self.bot.channel.is_direct = False c.execute(self.bot, 'SupportTeam') # as_command in group channel self.assertEqual(self.engine.mouth.get().text, u"Adding participants from 'SupportTeam'") with self.assertRaises(Exception): self.engine.mouth.get_nowait() self.assertEqual(self.bot.participants, ['*****@*****.**', '*****@*****.**'])
class HelpTests(unittest.TestCase): def setUp(self): self.engine = Engine(mouth=Queue()) self.engine.configure() self.engine.shell = Shell(engine=self.engine) self.bot = MyBot(engine=self.engine) def tearDown(self): del self.bot del self.engine collected = gc.collect() if collected: logging.info("Garbage collector: collected %d objects." % (collected)) def test_init(self): logging.info('***** init') c = Help(self.engine) self.assertEqual(c.keyword, u'help') self.assertEqual( c.information_message, u'Show commands and usage') self.assertEqual(c.usage_message, u'help <command>') self.assertFalse(c.is_hidden) c.execute(self.bot) self.assertEqual(self.engine.mouth.get().text, u'No command has been found.') with self.assertRaises(Exception): print(self.engine.mouth.get_nowait()) def test_execute_no_usage(self): logging.info('***** execute/no_usage') self.engine.shell.load_command(Command(keyword='hello', information_message='world')) c = Help(self.engine) c.execute(self.bot) self.assertEqual( self.engine.mouth.get().text, u'Available commands:\nhello - world') with self.assertRaises(Exception): self.engine.mouth.get_nowait() c.execute(self.bot, 'hello') self.assertEqual( self.engine.mouth.get().text, u'hello - world\nusage: hello') with self.assertRaises(Exception): self.engine.mouth.get_nowait() c.execute(self.bot, '*unknown*') self.assertEqual( self.engine.mouth.get().text, u'This command is unknown.') with self.assertRaises(Exception): self.engine.mouth.get_nowait() def test_help_true(self): logging.info('***** help/true') self.engine.shell.load_command('shellbot.commands.help') c = Help(self.engine) c.execute(self.bot) self.assertEqual( self.engine.mouth.get().text, u'Available commands:\nhelp - Show commands and usage') with self.assertRaises(Exception): self.engine.mouth.get_nowait() c.execute(self.bot, "help") self.assertEqual( self.engine.mouth.get().text, u'help - Show commands and usage\nusage: help <command>') with self.assertRaises(Exception): self.engine.mouth.get_nowait() def test_help_false(self): logging.info('***** help/false') c = Help(self.engine) c.execute(self.bot) self.assertEqual(self.engine.mouth.get().text, u'No command has been found.') with self.assertRaises(Exception): self.engine.mouth.get_nowait() c.execute(self.bot, u"*unknown*command*") self.assertEqual(self.engine.mouth.get().text, u'No command has been found.') with self.assertRaises(Exception): print(self.engine.mouth.get_nowait()) self.engine.load_command('shellbot.commands.help') c.execute(self.bot, "*unknown*command*") self.assertEqual(self.engine.mouth.get().text, u'This command is unknown.') with self.assertRaises(Exception): self.engine.mouth.get_nowait() def test_in_direct_or_in_group(self): logging.info('***** in_direct or in_group') c = Help(self.engine) self.engine.load_command('shellbot.commands.help') from shellbot.commands.base import Command class Custom(Command): keyword = 'custom' def execute(self, bot, arguments=None, **kwargs): bot.say("{}, really?".format(arguments)) self.engine.load_command(Custom(self.engine)) self.bot.channel.is_direct = False # group channel self.engine.shell.command('custom').in_direct = False self.engine.shell.command('custom').in_group = False c.execute(self.bot, "custom") self.assertEqual( self.engine.mouth.get().text, u'This command is unknown.') self.engine.shell.command('custom').in_direct = True self.engine.shell.command('custom').in_group = False c.execute(self.bot, "custom") self.assertEqual( self.engine.mouth.get().text, u'This command is unknown.') self.engine.shell.command('custom').in_direct = False self.engine.shell.command('custom').in_group = True c.execute(self.bot, "custom") self.assertEqual( self.engine.mouth.get().text, u'custom - None\nusage: custom') self.engine.shell.command('custom').in_direct = True self.engine.shell.command('custom').in_group = True c.execute(self.bot, "custom") self.assertEqual( self.engine.mouth.get().text, u'custom - None\nusage: custom') self.bot.channel.is_direct = True # direct channel self.engine.shell.command('custom').in_direct = False self.engine.shell.command('custom').in_group = False c.execute(self.bot, "custom") self.assertEqual( self.engine.mouth.get().text, u'This command is unknown.') self.engine.shell.command('custom').in_direct = True self.engine.shell.command('custom').in_group = False c.execute(self.bot, "custom") self.assertEqual( self.engine.mouth.get().text, u'custom - None\nusage: custom') self.engine.shell.command('custom').in_direct = False self.engine.shell.command('custom').in_group = True c.execute(self.bot, "custom") self.assertEqual( self.engine.mouth.get().text, u'This command is unknown.') self.engine.shell.command('custom').in_direct = True self.engine.shell.command('custom').in_group = True c.execute(self.bot, "custom") self.assertEqual( self.engine.mouth.get().text, u'custom - None\nusage: custom') with self.assertRaises(Exception): self.engine.mouth.get_nowait() def test_named_lists(self): logging.info('***** named lists') c = Help(self.engine) self.engine.configure_from_path(os.path.join( os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'test_settings', 'regular.yaml')) self.engine.shell = Shell(engine=self.engine) self.engine.load_command('shellbot.commands.help') class MyChannel(object): is_direct = True self.bot.channel = MyChannel() c.execute(self.bot) self.assertEqual( self.engine.mouth.get().text, u"Available commands:\nhelp - Show commands and usage") with self.assertRaises(Exception): self.engine.mouth.get_nowait() self.bot.channel.is_direct = False c.execute(self.bot) self.assertEqual( self.engine.mouth.get().text, u"Available commands:\nhelp - Show commands and usage\nSupportTeam - add participants ([email protected], ...)") with self.assertRaises(Exception): self.engine.mouth.get_nowait()